<?php
/**
 * 2007-2019 PrestaShop SA and Contributors.
 *
 * NOTICE OF LICENSE
 *
 * This source file is subject to the Academic Free License (AFL 3.0)
 * that is bundled with this package in the file LICENSE.txt.
 * It is also available through the world-wide-web at this URL:
 * https://opensource.org/licenses/AFL-3.0
 * If you did not receive a copy of the license and are unable to
 * obtain it through the world-wide-web, please send an email
 * to license@prestashop.com so we can send you a copy immediately.
 *
 * DISCLAIMER
 *
 * Do not edit or add to this file if you wish to upgrade PrestaShop to newer
 * versions in the future. If you wish to customize PrestaShop for your
 * needs please refer to http://www.prestashop.com for more information.
 *
 * @author    PrestaShop SA <contact@prestashop.com>
 * @copyright 2007-2019 PrestaShop SA and Contributors
 * @license   https://opensource.org/licenses/AFL-3.0  Academic Free License (AFL 3.0)
 * International Registered Trademark & Property of PrestaShop SA
 */

namespace Sibs;

use Configuration;
use Context;
use CurlHandle;
use Datetime;
use Exception;
use Order;
use OrderHistory;
use Sibs\Models\SibsCardTokens;
use Sibs\Models\SibsOrderRef;

class SibsPaymentCore
{
    /**
     * Acknowlegement Return Codes.
     *
     * @var array
     */
    protected static $ackReturnCodes = ['000'];

    /**
     * Get Checkout URL.
     *
     * @param string $serverMode
     * @return string
     */
    private static function getCheckoutUrl($serverMode)
    {
        $environment_file   = \Sibs::getEnvironmentConfig();
        $checkout_endpoints = $environment_file['checkout_endpoints'];

        return $checkout_endpoints[$serverMode];
    }

    /**
     * Get Payment URL.
     *
     * @param string $serverMode
     * @param string $referenceId
     * @return string
     */
    private static function getPaymentUrl($serverMode, $referenceId)
    {
        return self::getCheckoutUrl($serverMode) . "/{$referenceId}";
    }

    /**
     * Get Payment Status URL.
     *
     * @param string $serverMode
     * @param string $referenceId
     * @return string
     */
    private static function getPaymentStatusUrl($serverMode, $referenceId)
    {
        return self::getPaymentUrl($serverMode, $referenceId) . '/status';
    }

    /**
     * Get Capture URL.
     *
     * @param string $serverMode
     * @param string $referenceId
     * @return string
     */
    private static function getCaptureUrl($serverMode, $referenceId)
    {
        return self::getPaymentUrl($serverMode, $referenceId) . '/capture';
    }

    /**
     * Get Refund URL.
     *
     * @param string $serverMode
     * @param string $referenceId
     * @return string
     */
    private static function getRefundUrl($serverMode, $referenceId)
    {
        return self::getPaymentUrl($serverMode, $referenceId) . '/refund';
    }

    /**
     * Sets the ssl CURLOPT_SSL_VERIFYPEER.
     *
     * @param $ch
     * @param string $serverMode The server mode
     */
    public static function setSSLVerifyPeer($ch, string $serverMode): void
    {
        // In LIVE, we must verify SSL
        $verifyPeer = $serverMode === 'LIVE';

        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, $verifyPeer);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, $verifyPeer ? 2 : 0);

        // Set CA bundle if verifying peer
        if ($verifyPeer) {
            $caBundle = __DIR__ . '/certs/cacert.pem'; // point to a valid CA bundle
            if (file_exists($caBundle)) {
                curl_setopt($ch, CURLOPT_CAINFO, $caBundle);
            }
        }

        SibsLogger::info('verify_peer: ' . var_export($verifyPeer, true));
    }

    /**
     * Sets the Header.
     *
     * @param $ch
     * @param string
     */
    public static function setHeaders($ch, string $format, ?string $token): void
    {
        $headers = [
            "Content-Type: application/{$format}; charset=UTF-8",
        ];

        if ($token) {
            $clientID = Configuration::get('SIBS_GENERAL_CLIENTID');
            $headers[] = "Authorization: Bearer $token";
            $headers[] = "X-IBM-Client-ID: $clientID";
        }

        curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
        SibsLogger::info('headers: ' . SibsLogger::prettify($headers));
    }

    /**
     * Sets the Body.
     *
     * @param $ch
     * @param string $type
     * @param string $postFields
     */
    public static function setBody($ch, string $type = 'GET', $postFields = ''): void
    {
        switch (strtoupper($type)) {
            case 'POST':
                curl_setopt($ch, CURLOPT_POST, true);
                curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($postFields));
                break;
            case 'PUT':
            case 'DELETE':
            case 'PATCH':
                curl_setopt($ch, CURLOPT_CUSTOMREQUEST, strtoupper($type));
                if ($postFields) {
                    curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($postFields));
                }
                break;
            case 'GET':
            default:
                curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');
        }

        SibsLogger::info("type: $type");
        SibsLogger::info('postFields: ' . json_encode($postFields));
    }

    /**
     * get Curl error identifier translation.
     *
     * @param CurlHandle   $ch
     *
     * @return string
     */
    private static function getCurlErrorIdentifier(int $errno, string $error): string
    {
        $pluginErrorIdentifier = [
            60 => 'ERROR_MERCHANT_SSL_CERTIFICATE',
        ];

        return $pluginErrorIdentifier[$errno] ?? $error;
    }

    /**
     * Get a response from the gateway.
     *
     * @param string      $url
     * @param string      $serverMode
     * @param string      $type
     * @param string      $postFields
     * @param string      $format
     * @param null|string $token
     *
     * @return array
     */
    public static function getResponseData(
        string $url,
        string $serverMode,
        string $type = 'GET',
        $postFields = '',
        string $format = 'text/plain',
        $token = null
    ): array {
        SibsLogger::info('getResponseData()');

        $curlResponse = [
            'response' => null,
            'is_valid' => false,
        ];

        $ch = curl_init();
        try {
            curl_setopt($ch, CURLOPT_URL, $url);
            curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
            curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
            curl_setopt($ch, CURLOPT_TIMEOUT, 30);
            
            SibsLogger::info("url: $url");

            // SSL setup
            self::setSSLVerifyPeer($ch, $serverMode);

            // Headers
            self::setHeaders($ch, $format, $token);

            // Request body / method
            self::setBody($ch, $type, $postFields);

            // Execute request
            $responseBody = curl_exec($ch);
            $curlErrno    = curl_errno($ch);
            $curlError    = curl_error($ch);

            // Handle response
            if ($curlErrno) {
                $curlResponse = [
                    'response' => self::getCurlErrorIdentifier($curlErrno, $curlError),
                    'is_valid' => false,
                ];
            } else {
                $decoded = json_decode($responseBody, true);
                $curlResponse = [
                    'response' => $decoded !== null ? $decoded : $responseBody,
                    'is_valid' => true,
                ];
            }

        } finally {
            if (is_resource($ch) || $ch instanceof CurlHandle) {
                curl_close($ch);
            }
        }

        SibsLogger::info('curlResponse: ' . json_encode($curlResponse));

        return $curlResponse;
    }

    /**
     * Get Credential Parameters.
     *
     * @param array $transactionData
     * @return array
     */
    private static function getCredentialParameter($transactionData)
    {
        $parameters = [
            'channel' => $transactionData['channel_id'],
        ];

        // test mode parameters (true)
        if (! empty($transactionData['test_mode'])) {
            $parameters['testMode'] = $transactionData['test_mode'];
        }

        return $parameters;
    }

    /**
     * Set Number Format.
     *
     * @param mixed $number
     * @return string
     */
    public static function setNumberFormat($number)
    {
        return number_format(str_replace(',', '.', $number), 2, '.', '');
    }

    /**
     * Get Checkout Parameter.
     *
     * @param array $transactionData
     * @param string $lang
     * @return array
     */
    public static function getCheckoutParameter($transactionData, $lang = 'en')
    {
        define('DATE_FORMAT', 'Y-m-d\TH:i:s.vP');

        $now = new DateTime();

        $terminalID            = (int) Configuration::get('SIBS_GENERAL_TERMINALID');
        $credentials           = self::getCredentialParameter($transactionData);
        $paymentType           = self::sibs_spg_get_payment_type($transactionData['payment_type']);
        $paymentMethod         = self::sibs_get_payment_method_for_spg($transactionData['payment_method']);
        $tansactionDescription = "Transaction for order number {$transactionData['id_transaction']} terminalId $terminalID";

        $parameters = [
            'merchant' => [
                'terminalId'             => $terminalID,
                'channel'                => $credentials['channel'],
                'merchantTransactionId'  => $transactionData['id_transaction'],
                'transactionDescription' => $tansactionDescription,
                'shopURL'                => _PS_BASE_URL_ . __PS_BASE_URI__,
            ],
            'transaction' => [
                'transactionTimestamp' => $now->format(DATE_FORMAT),
                'description'          => $tansactionDescription,
                'moto'                 => false,
                'paymentType'          => $paymentType,
                'paymentMethod'        => $paymentMethod,
                'amount'               => [
                    'value'    => floatval(self::setNumberFormat($transactionData['amount'])),
                    'currency' => $transactionData['currency'],
                ],
            ],
            'customer' => [
                'customerInfo' => [
                    'customerName'     => $transactionData['customer']['first_name'] . ' ' . $transactionData['customer']['last_name'],
                    'customerEmail'    => $transactionData['customer']['email'],
                    'customerLanguage' => $lang,
                    'shippingAddress'  => [
                        'street1'  => $transactionData['shipping']['street'],
                        'city'     => $transactionData['shipping']['city'],
                        'postcode' => $transactionData['shipping']['zip'],
                        'country'  => $transactionData['shipping']['country_code'],
                    ],
                    'billingAddress' => [
                        'street1'  => $transactionData['billing']['street'],
                        'city'     => $transactionData['billing']['city'],
                        'postcode' => $transactionData['billing']['zip'],
                        'country'  => $transactionData['billing']['country_code'],
                    ],
                ],
            ],
            'info' => [
                'deviceInfo' => [
                    'applicationName'    => 'prestashop:' . _PS_VERSION_,
                    'applicationVersion' => SibsConstants::SIBS_PLUGIN_VESION,
                ],
            ],
        ];

        if (in_array(SibsConstants::PAYMENT_METHOD_PAY_BY_LINK, $paymentMethod)) {
            $parameters['transaction'] = array_merge_recursive($parameters['transaction'], self::getCheckoutParameterPayByLink($now));
        }

        if (in_array(SibsConstants::PAYMENT_METHOD_CARD, $paymentMethod)) {
            $parameters = array_merge_recursive($parameters, self::getCheckoutParameterOneclick());
        }

        return $parameters;
    }

    /**
     * Get Checkout Parameter Pay By Link.
     *
     * @param Datetime $now
     * @return array
     */
    public static function getCheckoutParameterPayByLink($now)
    {
        $paybylinkParameters = [];

        if (! is_null(Configuration::get('SIBS_PAY_BY_LINK_EXPIRATION_PAYMENT_VALUE'))) {
        }
        //removendo as configuracoes
        $varPtmntTime           = 3;
        $varPtmntTimeTypeOffset = 'day';

        $abs_number         = abs(intval($varPtmntTime));
        $varPtmntTimeOffset = "+$abs_number $varPtmntTimeTypeOffset";

        $now->modify($varPtmntTimeOffset);

        $paybylinkParameters = [
            'payByLink' => [
                'expirationDateTime'     => $now->format(DATE_FORMAT),
                'linkExpirationDateTime' => $now->format(DATE_FORMAT),
            ],
        ];

        return $paybylinkParameters;
    }

    /**
     * Get Checkout Parameter Oneclick.
     *
     * @return array
     */
    public static function getCheckoutParameterOneclick()
    {
        $context  = Context::getContext();
        $oneclick = $context->customer->isLogged() ? Configuration::get('SIBS_CC_ONECLICK') : SibsConstants::SIBS_TOKEN_NONE;

        switch($oneclick) {
            case SibsConstants::SIBS_TOKEN_TOKENIZATION:
                $tokeniseCard       = true;
                $customerAcceptance = false;
                $paymentTokens      = self::getCardTokens();

                break;
            case SibsConstants::SIBS_TOKEN_ONECLICK:
                $tokeniseCard       = ! empty($_POST['sibsCustomerAcceptor']) ? true : false;
                $customerAcceptance = ! empty($_POST['sibsCustomerAcceptor']) ? true : false;
                $paymentTokens      = ! empty($_POST['sibsCustomerAcceptor']) ? self::getCardTokens() : [];

                break;
            case SibsConstants::SIBS_TOKEN_NONE:
            default:
                $tokeniseCard       = false;
                $customerAcceptance = false;
                $paymentTokens      = [];
        }

        $oneclickParameters = [
            'transaction' => [
                'oneClick' => [
                    'customerAcceptance' => $customerAcceptance,
                ],
            ],
            'tokenisation' => [
                'tokenisationRequest' => [
                    'tokeniseCard' => $tokeniseCard,
                ],
                'paymentTokens' => $paymentTokens,
            ],
        ];

        return $oneclickParameters;
    }

    /**
     * Get Card Tokens.
     *
     * @return array
     */
    public static function getCardTokens()
    {
        $context = Context::getContext();

        if ($context->customer->isLogged()) {
            $customerId = $context->customer->id;
            $dbResponse = SibsCardTokens::getCardTokensByCustomer($customerId);

            $tokenFunction = function (array $tokenDB) {
                return [
                    'tokenType' => $tokenDB['token_type'],
                    'value'     => $tokenDB['value'],
                ];
            };

            return array_map($tokenFunction, $dbResponse);
        }

        return [];
    }

    /**
     * Get Backoffice Parameter.
     *
     * @param array $transactionData
     * @return array
     */
    private static function getBackOfficeParameter($transactionData)
    {
        SibsLogger::info('transactionData: ' . json_encode($transactionData));

        return $transactionData;
    }

    /**
     * Is Payment GET Response.
     *
     * @param string $paymentStatusUrl
     * @param mixed $resultJson
     * @param string $serverMode
     * @param mixed $token
     * @return bool
     */
    private static function isPaymentGetResponse($paymentStatusUrl, &$resultJson, $serverMode, $token)
    {
        for ($i = 0; $i < 3; $i++) {
            $response = true;

            try {
                $resultJson = self::getResponseData(
                    $paymentStatusUrl,
                    $serverMode,
                    'GET',
                    '',
                    'json',
                    $token
                );
            } catch (Exception $e) {
                $response = false;
            }

            if ($response && $resultJson) {
                return true;
            }
        }

        return false;
    }

    /**
     * Get Checkout Result.
     *
     * @param array $transactionData
     * @param string $lang
     * @return array $response
     */
    public static function getCheckoutResult($transactionData, $lang = 'en')
    {
        SibsLogger::info('getCheckoutResult()');

        $checkoutUrl = self::getCheckoutUrl($transactionData['server_mode']);
        $postData    = self::getCheckoutParameter($transactionData, $lang);
        $token       = $transactionData['token'];

        $response = self::getResponseData(
            $checkoutUrl,
            $transactionData['server_mode'],
            'POST',
            $postData,
            'json',
            $token
        );

        return $response;
    }

    /**
     * Get Payment Widget URL.
     *
     * @param array $transactionData
     * @param string $checkoutId
     * @param array $widget_endpoints
     * @return string
     */
    public static function getPaymentWidgetUrl($transactionData, $checkoutId, $widget_endpoints)
    {
        $serverMode = $transactionData['server_mode'];

        return $widget_endpoints[$serverMode] . $checkoutId;
    }

    /**
     * Get Payment Status.
     *
     * @param string $checkoutId
     * @param array $transactionData
     * @return mixed
     */
    public static function getPaymentStatus($checkoutId, $transactionData)
    {
        $paymentStatusUrl = self::getPaymentStatusUrl($transactionData['server_mode'], $checkoutId);
        $resultJson       = '';
        $token            = $transactionData['token'];
        $response         = self::isPaymentGetResponse($paymentStatusUrl, $resultJson, $transactionData['server_mode'], $token);

        if ($response && isset($resultJson['response']['returnStatus']['statusCode']) && $resultJson['response']['returnStatus']['statusCode'] == '000') {
            return $resultJson;
        }

        return false;
    }

    /**
     * Get Payment Server To Server Status.
     *
     * @param string $checkoutId
     * @param array  $transactionData
     * @return mixed
     */
    public static function getPaymentServerToServerStatus($checkoutId, $transactionData)
    {
        $paymentStatusUrl = self::getPaymentUrl($transactionData['server_mode'], $checkoutId);
        $paymentStatusUrl .= '?' . http_build_query(self::getCredentialParameter($transactionData));
        $resultJson = '';
        $token      = $transactionData['token'];
        $response   = self::isPaymentGetResponse($paymentStatusUrl, $resultJson, $transactionData['server_mode'], $token);

        if ($response) {
            return $resultJson;
        }

        return false;
    }

    /**
     * BackOffice Operation.
     *
     * @param string $referenceId
     * @param array $transactionData
     * @return array
     */
    public static function backOfficeOperation($referenceId, $transactionData)
    {
        SibsLogger::info("referenceId: $referenceId");
        SibsLogger::info('transactionData: ' . SibsLogger::prettify($transactionData));

        $paymentType = $transactionData['paymentType'];

        if ($paymentType == SibsConstants::PAYMENT_MODE_CAPT) {
            $resultJson = self::backOfficeOperationCapture($referenceId, $transactionData);
        } elseif ($paymentType == SibsConstants::PAYMENT_MODE_RFND) {
            $resultJson = self::backOfficeOperationRefund($referenceId, $transactionData);
        } elseif ($paymentType == SibsConstants::PAYMENT_MODE_RVSL) {
            $resultJson = self::backOfficeOperationReversal($referenceId, $transactionData);
        } else {
            $resultJson = [];
        }

        SibsLogger::info('backoffice response: ' . json_encode($resultJson));

        return $resultJson;
    }

    /**
     * BackOffice Operations Capture.
     *
     * @param string $referenceId
     * @param array $transactionData
     * @return array
     */
    public static function backOfficeOperationCapture($referenceId, $transactionData)
    {
        $token         = $transactionData['token'];
        $servermode    =  $transactionData['server_mode'];
        $backOfficeUrl = self::getCaptureUrl($transactionData['server_mode'], $referenceId);

        unset($transactionData['paymentType']);
        unset($transactionData['token']);
        unset($transactionData['test_mode']);
        unset($transactionData['amount']);
        unset($transactionData['currency']);

        $postData = self::getBackOfficeParameter($transactionData);

        return self::getResponseData(
            $backOfficeUrl,
            $servermode,
            'POST',
            $postData,
            'json',
            $token
        );
    }

    /**
     * BackOffice Operation Refund.
     *
     * @param string $referenceId
     * @param array $transactionData
     * @return array
     */
    public static function backOfficeOperationRefund($referenceId, $transactionData)
    {
        $refund_status = SibsOrderRef::getRefundStatus($transactionData['originalTransaction']['id']);
        SibsLogger::info("refund_status: $refund_status");

        if ($refund_status === SibsConstants::CAPTURE_REFUND_STATUS_PENDING) {
            $resultJson['refund_pending'] = true;

            return $resultJson;
        }

        $token         = $transactionData['token'];
        $servermode    = $transactionData['server_mode'];
        $backOfficeUrl = self::getRefundUrl($transactionData['server_mode'], $referenceId);

        unset($transactionData['paymentType']);
        unset($transactionData['token']);
        unset($transactionData['server_mode']);

        $postData = self::getBackOfficeParameter($transactionData);

        return self::getResponseData(
            $backOfficeUrl,
            $servermode,
            'POST',
            $postData,
            'json',
            $token
        );
    }

    /**
     * BackOffice Operation Reversal.
     *
     * @param string $referenceId
     * @param array $transactionData
     * @return array
     */
    public static function backOfficeOperationReversal($referenceId, $transactionData)
    {
        return [];
    }

    /**
     * Get Server To Server Response.
     *
     * @param array $transactionData
     * @return string|bool
     */
    public static function getServerToServerResponse($transactionData)
    {
        $backOfficeUrl = self::getCheckoutUrl($transactionData['server_mode']);
        $postData      = self::getCheckoutParameter($transactionData);
        $token         = $transactionData['token'];

        return self::getResponseData(
            $backOfficeUrl,
            $transactionData['server_mode'],
            'POST',
            $postData,
            'json',
            $token
        );
    }

    /**
     * Get Transaction Result.
     *
     * @param int $returnCode
     * @param bool $paymentStatus
     * @return string
     */
    public static function getTransactionResult($returnCode = false, $paymentStatus = false)
    {
        if ($returnCode && $paymentStatus) {
            $acceptPaymentStatus = self::sibs_accept_response_status($paymentStatus);

            if (in_array($returnCode, self::$ackReturnCodes) && $acceptPaymentStatus) {
                return SibsConstants::SIBS_ACK;
            }
        }

        return SibsConstants::SIBS_NOK;
    }

    /**
     * Get Error Indentifier.
     *
     * @return string
     */
    public static function getErrorIdentifier()
    {
        return 'Unfortunately, your attempt failed.';
    }

    /**
     * SIBS SPG Get Payment Type.
     *
     * @param string $payment_type
     * @return string
     */
    public static function sibs_spg_get_payment_type($payment_type)
    {
        switch ($payment_type) {
            case SibsConstants::PAYMENT_MODE_AUTH:
                return SibsConstants::PAYMENT_TYPE_AUTH;
            case SibsConstants::PAYMENT_MODE_DEBIT:
            case SibsConstants::PAYMENT_MODE_PAY_BY_LINK:
            case SibsConstants::PAYMENT_MODE_XPAY:
                return SibsConstants::PAYMENT_TYPE_PURS;
            case SibsConstants::PAYMENT_MODE_CAPT:
                return SibsConstants::PAYMENT_TYPE_CAPT;
            case SibsConstants::PAYMENT_MODE_RFND:
                return SibsConstants::PAYMENT_TYPE_RFND;
            default:
                return $payment_type;
        }
    }

    /**
     * Translate from Plugin payment identifier to SPG payment methods.
     *
     * @param string $payment_id payment identifier
     * @return array SPG payment method
     */
    public static function sibs_get_payment_method_for_spg($payment_id)
    {
        switch ($payment_id) {
            case SibsConstants::PAYMENT_METHOD_CREDIT_CARD:
                return [
                    SibsConstants::PAYMENT_METHOD_CARD,
                ];
            case SibsConstants::PAYMENT_METHOD_BLIK:
                return [
                    SibsConstants::PAYMENT_METHOD_BLIK,
                ];
            case SibsConstants::PAYMENT_METHOD_XPAY:
                return [
                    SibsConstants::PAYMENT_METHOD_XPAY,
                ];
            case SibsConstants::PAYMENT_METHOD_PAY_BY_LINK:
                return [
                    SibsConstants::PAYMENT_METHOD_PAY_BY_LINK,
                    //SibsConstants::PAYMENT_METHOD_PAY_BY_LINK_KEVIN,
                ];
            default:
                return [];
        }
    }

    /**
     * Convert SPG payment type to DPG payment type.
     *
     * @param string $spg_payment_type SPG payment type
     * @return string DPG payment type
     */
    public static function sibs_convert_spg_payment_type($spg_payment_type)
    {
        switch ($spg_payment_type) {
            case SibsConstants::PAYMENT_TYPE_AUTH:
                return SibsConstants::PAYMENT_MODE_AUTH;
            case SibsConstants::PAYMENT_TYPE_PREF:
            case SibsConstants::PAYMENT_TYPE_PURS:
                return SibsConstants::PAYMENT_MODE_DEBIT;
            case SibsConstants::PAYMENT_TYPE_CAPT:
                return SibsConstants::PAYMENT_MODE_CAPT;
            case SibsConstants::PAYMENT_TYPE_RFND:
                return SibsConstants::PAYMENT_MODE_RFND;
            case SibsConstants::PAYMENT_TYPE_RVSL:
                return SibsConstants::PAYMENT_MODE_RVSL;
            case SibsConstants::PAYMENT_TYPE_PBL:
                return SibsConstants::PAYMENT_MODE_PAY_BY_LINK;
            case SibsConstants::PAYMENT_TYPE_CAUT:
            case SibsConstants::PAYMENT_TYPE_CPRF:
            case SibsConstants::PAYMENT_TYPE_STIQ:
            case SibsConstants::PAYMENT_TYPE_RCON:
            default:
                return '';
        }
    }

    /**
     * Convert  payment status to Prestashop status.
     *
     * @param string $paymentMethod  payment method
     * @param string $paymentStatus  payment status
     * @return string Prestashop status
     */
    public static function sibs_convert_response_status_to_payment_status($paymentMethod, $paymentStatus)
    {
        $auth_or_debit_status = self::sibs_get_auth_or_debit_status($paymentMethod);
        SibsLogger::info('auth_or_debit_status: ' . $auth_or_debit_status);
        SibsLogger::info('paymentStatus: ' . $paymentStatus);

        switch ($paymentStatus) {
            case SibsConstants::PAYMENT_STATUS_SUCCESS:
            case SibsConstants::PAYMENT_STATUS_PARTIAL:
                return $auth_or_debit_status;
            case SibsConstants::PAYMENT_STATUS_INPROCESSING:
            case SibsConstants::PAYMENT_STATUS_PENDING:
                return Configuration::get(SibsConstants::ORDER_STATUS_SIBS_PENDING);
            case SibsConstants::PAYMENT_STATUS_DECLINED:
            case SibsConstants::PAYMENT_STATUS_TIMEOUT:
            case SibsConstants::PAYMENT_STATUS_ERROR:
            default:
                return Configuration::get(SibsConstants::ORDER_STATUS_CANCELED);
        }
    }

    /**
     * SIBS Get AUTH or DEBIT Status.
     *
     * @param string $spg_payment_method
     * @return string
     */
    public static function sibs_get_auth_or_debit_status($spg_payment_method)
    {
        switch($spg_payment_method) {
            case SibsConstants::PAYMENT_METHOD_CARD:
            case SibsConstants::PAYMENT_METHOD_TOKEN:
            case SibsConstants::PAYMENT_METHOD_CREDIT_CARD:
                return self::sibs_return_status_from_mode(Configuration::get('SIBS_CC_MODE'));
            case SibsConstants::PAYMENT_METHOD_BLIK:
                return self::sibs_return_status_from_mode(Configuration::get('SIBS_BLIK_MODE'));
            case SibsConstants::PAYMENT_METHOD_XPAY:
                return self::sibs_return_status_from_mode(Configuration::get('SIBS_XPAY_MODE'));
            case SibsConstants::PAYMENT_METHOD_PAY_BY_LINK:
            case SibsConstants::PAYMENT_METHOD_PAY_BY_LINK_KEVIN:
                return self::sibs_return_status_from_mode(Configuration::get('SIBS_PAY_BY_LINK_MODE'));
            default:
                return Configuration::get(SibsConstants::ORDER_STATUS_ERROR);
        }
    }

    /**
     * SIBS Return Status From Mode.
     *
     * @param string $mode
     * @return string
     */
    public static function sibs_return_status_from_mode($mode)
    {
        if ($mode === SibsConstants::PAYMENT_MODE_AUTH) {
            return Configuration::get(SibsConstants::ORDER_STATUS_SIBS_AUTHORIZED);
        }

        return Configuration::get(SibsConstants::ORDER_STATUS_PAYMENT);
    }

    /**
     * Accept SPG Status.
     *
     * @param string $paymentStatus payment status
     * @return bool Prestashop success
     */
    public static function sibs_accept_response_status($paymentStatus)
    {
        switch ($paymentStatus) {
            case SibsConstants::PAYMENT_STATUS_SUCCESS:
            case SibsConstants::PAYMENT_STATUS_PARTIAL:
            case SibsConstants::PAYMENT_STATUS_INPROCESSING:
            case SibsConstants::PAYMENT_STATUS_PENDING:
                $acptStatus = true;

                break;
            case SibsConstants::PAYMENT_STATUS_DECLINED:
            case SibsConstants::PAYMENT_STATUS_TIMEOUT:
            case SibsConstants::PAYMENT_STATUS_ERROR:
            default:
                $acptStatus = false;

                break;
        }

        return $acptStatus;
    }

    /**
     * SIBS Convert Response Status To Capture Payment Status.
     *
     * @param string $captureRefundStatus
     * @return string
     */
    public static function sibs_convert_response_status_to_capture_payment_status($captureRefundStatus)
    {
        switch ($captureRefundStatus) {
            case SibsConstants::PAYMENT_STATUS_SUCCESS:
            case SibsConstants::PAYMENT_STATUS_PARTIAL:
                return SibsConstants::CAPTURE_REFUND_STATUS_SUCCESS;
            case SibsConstants::PAYMENT_STATUS_INPROCESSING:
            case SibsConstants::PAYMENT_STATUS_PENDING:
                return SibsConstants::CAPTURE_REFUND_STATUS_PENDING;
            case SibsConstants::PAYMENT_STATUS_DECLINED:
            case SibsConstants::PAYMENT_STATUS_TIMEOUT:
            case SibsConstants::PAYMENT_STATUS_ERROR:
            default:
                return SibsConstants::CAPTURE_REFUND_STATUS_FAILED;
        }
    }

    /**
     * Get Order Refund Status.
     *
     * @param string $refundStatus
     * @return string
     */
    public static function getOrderRefundStatus($refundStatus)
    {
        switch($refundStatus) {
            case SibsConstants::PAYMENT_STATUS_INPROCESSING:
            case SibsConstants::PAYMENT_STATUS_PENDING:
                return SibsConstants::ORDER_STATUS_SIBS_REFUND_PENDING;
            case SibsConstants::PAYMENT_STATUS_SUCCESS:
            case SibsConstants::PAYMENT_STATUS_PARTIAL:
            default:
                return SibsConstants::ORDER_STATUS_REFUND;
        }
    }

    /**
     * Save Order History.
     *
     * @param int $orderID
     * @param string $orderStatus
     * @param int|null $employeeID
     * @return void
     */
    public static function saveOrderHistory($orderID, $orderStatus, $employeeID = null)
    {
        $order = new Order($orderID);
        // payment accepted status code RF
        $id_order_status = Configuration::get($orderStatus);
        // update order state to code RF
        $new_history = new OrderHistory();

        if (is_null($employeeID)) {
            $new_history->id_employee = $employeeID;
        }

        $new_history->id_order = $orderID;
        $new_history->changeIdOrderState((int) $id_order_status, $order, true);
        $new_history->add();
    }

    /**
     * Save Order History With Email.
     *
     * @param int $orderID
     * @param string $orderStatus
     * @param int $employeeID
     * @return void
     */
    public static function saveOrderHistoryWithEmail($orderID, $orderStatus, $employeeID = null)
    {
        $order = new Order($orderID);
        // payment accepted status code RF
        $id_order_status = Configuration::get($orderStatus);
        // update order state to code RF
        $new_history = new OrderHistory();

        if (is_null($employeeID)) {
            $new_history->id_employee = $employeeID;
        }

        $new_history->id_order = $orderID;
        $new_history->changeIdOrderState((int) $id_order_status, $order, true);
        $new_history->add();
    }
}
