<?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
 */
if (! defined('_PS_VERSION_')) {
    exit;
}

require_once __DIR__ . '/vendor/autoload.php';

use PrestaShop\PrestaShop\Core\Domain\Order\CancellationActionType;
use PrestaShop\PrestaShop\Core\Payment\PaymentOption;
use Sibs\SibsConstants;
use Sibs\SibsException;
use Sibs\SibsLog;
use Sibs\SibsModels;
use Sibs\SibsPaymentCore;
use Sibs\SibsUtils;

class Sibs extends PaymentModule
{
    protected $html = '';

    public $payment_methods = [
        SibsConstants::PAYMENT_METHOD_CREDIT_CARD,
        SibsConstants::PAYMENT_METHOD_BLIK,
        SibsConstants::PAYMENT_METHOD_PAY_BY_LINK,
    ];

    public $db_pa_payment_methods = [
        SibsConstants::PAYMENT_METHOD_CREDIT_CARD,
        SibsConstants::PAYMENT_METHOD_BLIK,
        SibsConstants::PAYMENT_METHOD_PAY_BY_LINK,
    ];

    public $card_payment_methods = [
        SibsConstants::PAYMENT_METHOD_CREDIT_CARD,
    ];

    public function __construct()
    {
        $this->version                = SibsConstants::SIBS_PLUGIN_VESION;
        $this->name                   = SibsConstants::SIBS_PLUGIN_NAME;
        $this->tab                    = SibsConstants::SIBS_PLUGIN_TAB;
        $this->ps_versions_compliancy = SibsConstants::SIBS_PRESTASHOP_VERSION_COMPLIANCY;
        $this->author                 = SibsConstants::SIBS_PLUGIN_AUTHOR;
        $this->bootstrap              = SibsConstants::SIBS_PLUGIN_BOOTSTRAP;

        parent::__construct();

        $this->displayName = SibsConstants::SIBS_DISPLAY_NAME;
        $this->description = $this->l('Accepts payments by SIBS');

        if (! SibsModels::isPluginVersionUpdated($this->version)) {
            SibsModels::updatePluginVersion($this->version, $this->name);
        }

        $this->confirmUninstall = ($this->l('BACKEND_TT_DELETE_DETAILS') !== 'BACKEND_TT_DELETE_DETAILS') ?
            $this->l('BACKEND_TT_DELETE_DETAILS') :
            'Are you sure you want to delete your details?';
    }

    public function install()
    {
        SibsLog::warning('DEBUG: install....');

        try {
            if (! function_exists('curl_init')) {
                $errorMessage = ($this->l('ERROR_MESSAGE_CURL_REQUIRED') !== 'ERROR_MESSAGE_CURL_REQUIRED') ?
                    $this->l('ERROR_MESSAGE_CURL_REQUIRED') :
                    'cURL is required to use this module. Please install the php extention cURL.';

                throw new SibsException($errorMessage);
            }

            $installResult = parent::install();

            if (! $installResult) {
                $errorMessage = ($this->l('ERROR_MESSAGE_INSTALL_MODULE') !== 'ERROR_MESSAGE_INSTALL_MODULE') ?
                    $this->l('ERROR_MESSAGE_INSTALL_MODULE') :
                    'There was an Error installing the module.';

                throw new SibsException($errorMessage);
            }

            $hooksResult = (
                $this->registerHook('header') &&
               // $this->registerHook('displayAdminOrder') &&
                $this->registerHook('displayAdminOrderMain') && //this is the hook
                $this->registerHook('displayAdminOrderSide') && //this is the hook
                $this->registerHook('displayFooter') &&
                $this->registerHook('paymentReturn') &&
                $this->registerHook('updateOrderStatus') &&
                $this->registerHook('displayInvoice') &&
                $this->registerHook('paymentOptions') &&
                $this->registerHook('displayTop') &&
                $this->registerHook('moduleRoutes') &&
                $this->registerHook('actionEmailAddAfterContent') &&
                $this->registerHook('actionProductCancel') &&
                $this->registerHook('actionValidateCustomerAddressForm') &&
                $this->registerHook('actionPaymentCCAdd')
            );

            if (! $hooksResult) {
                $errorMessage = ($this->l('ERROR_MESSAGE_REGISTER_HOOK') !== 'ERROR_MESSAGE_REGISTER_HOOK') ?
                    $this->l('ERROR_MESSAGE_REGISTER_HOOK') :
                    'There was an Error on register the module hooks.';

                throw new SibsException($errorMessage);
            }

            $tablesResult = (
                SibsModels::createOrderRefTables() &&
                SibsModels::createTokenizationTable()
            );

            if (! $tablesResult) {
                $errorMessage = ($this->l('ERROR_MESSAGE_CREATE_TABLE') !== 'ERROR_MESSAGE_CREATE_TABLE') ?
                    $this->l('ERROR_MESSAGE_CREATE_TABLE') :
                    'There was an Error creating a custom table.';

                throw new SibsException($errorMessage);
            }

            $orderStatusResult = $this->addSibsOrderStatus();

            if (! $orderStatusResult) {
                $errorMessage = ($this->l('ERROR_MESSAGE_CREATE_ORDER_STATUS') !== 'ERROR_MESSAGE_CREATE_ORDER_STATUS') ?
                    $this->l('ERROR_MESSAGE_CREATE_ORDER_STATUS') :
                    'There was an Error creating a custom order status.';

                throw new SibsException($errorMessage);
            }

            $configurationResult = $this->setConfigurationResult();

            if (! $configurationResult) {
                $errorMessage = ($this->l('ERROR_MESSAGE_DEFAULT_CONFIGURATION') !== 'ERROR_MESSAGE_DEFAULT_CONFIGURATION') ?
                    $this->l('ERROR_MESSAGE_DEFAULT_CONFIGURATION') :
                    'There was an Error on setting the default configurations.';

                throw new SibsException($errorMessage);
            }
        } catch (SibsException $_e) {
            $this->warning = $_e->getErrorMessage();

            return false;
        } catch (Exception $e) {
            SibsLog::critical($e->getMessage());
            $this->warning = $e->getMessage();

            return false;
        }

        return true;
    }

    public function setConfigurationResult()
    {
        SibsLog::warning('DEBUG: setConfigurationResult....');
        // default general setting.
        $configurationResult = (
            Configuration::updateValue('SIBS_POPUP', true) &&

            // UPDATE SIBS GENERALS
            Configuration::updateValue('SIBS_GENERAL_CLIENTID', '') &&
            Configuration::updateValue('SIBS_GENERAL_TERMINALID', '') &&
            Configuration::updateValue('SIBS_GENERAL_BEARER', '') &&
            Configuration::updateValue('SIBS_WEBHOOK_SECRET', '') &&
            Configuration::updateValue('SIBS_GENERAL_ENVIRONMENT', '') &&

            // UPDATE SIBS ACTIVE
            Configuration::updateValue('SIBS_CC_ACTIVE', '1') &&
            Configuration::updateValue('SIBS_BLIK_ACTIVE', '1') &&
            Configuration::updateValue('SIBS_PAY_BY_LINK_ACTIVE', '1') &&

            // UPDATE MODES
            Configuration::updateValue('SIBS_CC_MODE', SibsConstants::PAYMENT_MODE_DEBIT) &&
            Configuration::updateValue('SIBS_BLIK_MODE', SibsConstants::PAYMENT_MODE_DEBIT) &&
            Configuration::updateValue('SIBS_PAY_BY_LINK_MODE', SibsConstants::PAYMENT_MODE_PAY_BY_LINK) &&

            // UPDATE SIBS SORT
            Configuration::updateValue('SIBS_CC_SORT', '1') &&
            Configuration::updateValue('SIBS_BLIK_SORT', '2') &&
            Configuration::updateValue('SIBS_PAY_BY_LINK_SORT', '3') &&

            // UPDATE PAY BY LINK DATA
            Configuration::updateValue('SIBS_PAY_BY_LINK_EXPIRATION_PAYMENT_VALUE', '60') &&
            Configuration::updateValue('SIBS_PAY_BY_LINK_EXPIRATION_PAYMENT_TYPE', 'minute') &&

            // UPDATE BLIK DATA
            Configuration::updateValue('SIBS_BLIK_NUMBER_OF_RETRIES_VALUE', '30') &&
            Configuration::updateValue('SIBS_BLIK_DELAY_BETWEEN_RETRIES_VALUE', '1') &&

            // UPDATE CARDS
            Configuration::updateValue('SIBS_CC_CARDS', '') &&

            // UPDATE CARD DATA
            Configuration::updateValue('SIBS_CC_ONECLICK', SibsConstants::SIBS_TOKEN_NONE)
        );

        return $configurationResult;
    }

    public function uninstall()
    {
        SibsLog::warning('DEBUG: uninstall....');

        $deleteConfigurationResult = $this->deleteConfigurationResult();

        if (! $deleteConfigurationResult) {
            return false;
        }

        $unregisterHookResult = (
            $this->unregisterHook('header') &&
          //  $this->unregisterHook('displayAdminOrder') &&
            $this->unregisterHook('displayAdminOrderMain') &&
            $this->unregisterHook('displayAdminOrderSide') &&
            $this->unregisterHook('displayFooter') &&
            $this->unregisterHook('paymentReturn') &&
            $this->unregisterHook('updateOrderStatus') &&
            $this->unregisterHook('displayInvoice') &&
            $this->unregisterHook('paymentOptions') &&
            $this->unregisterHook('displayTop') &&
            $this->unregisterHook('moduleRoutes') &&
            $this->unregisterHook('actionEmailAddAfterContent') &&
            $this->unregisterHook('actionProductCancel') &&
            $this->unregisterHook('actionPaymentCCAdd')
        );

        if (! $unregisterHookResult) {
            return false;
        }

        $uninstallResult = parent::uninstall();

        if (! $uninstallResult) {
            return false;
        }

        return true;
    }

    public function deleteConfigurationResult()
    {
        SibsLog::warning('DEBUG: deleteConfigurationResult....');

        $deleteConfigurationResult = (
            Configuration::deleteByName('SIBS_POPUP') &&

            // DELETE SIBS GENERALS
            Configuration::deleteByName('SIBS_GENERAL_CLIENTID') &&
            Configuration::deleteByName('SIBS_GENERAL_TERMINALID') &&
            Configuration::deleteByName('SIBS_GENERAL_BEARER') &&
            Configuration::deleteByName('SIBS_WEBHOOK_SECRET') &&
            Configuration::deleteByName('SIBS_GENERAL_ENVIRONMENT') &&

            // DELETE SIBS ACTIVE
            Configuration::deleteByName('SIBS_CC_ACTIVE') &&
            Configuration::deleteByName('SIBS_BLIK_ACTIVE') &&
            Configuration::deleteByName('SIBS_PAY_BY_LINK_ACTIVE') &&

            // DELETE MODES
            Configuration::deleteByName('SIBS_CC_MODE') &&
            Configuration::deleteByName('SIBS_BLIK_MODE') &&
            Configuration::deleteByName('SIBS_PAY_BY_LINK_MODE') &&

            // DELETE SIBS SORT
            Configuration::deleteByName('SIBS_CC_SORT') &&
            Configuration::deleteByName('SIBS_BLIK_SORT') &&
            Configuration::deleteByName('SIBS_PAY_BY_LINK_SORT') &&

            // DELETE PAY BY LINK DATA
            Configuration::deleteByName('SIBS_PAY_BY_LINK_EXPIRATION_PAYMENT_VALUE') &&
            Configuration::deleteByName('SIBS_PAY_BY_LINK_EXPIRATION_PAYMENT_TYPE') &&

            // DELETE BLIK DATA
            Configuration::deleteByName('SIBS_BLIK_NUMBER_OF_RETRIES_VALUE') &&
            Configuration::deleteByName('SIBS_BLIK_DELAY_BETWEEN_RETRIES_VALUE') &&

            // DELETE CARDS
            Configuration::deleteByName('SIBS_CC_CARDS') &&

            // DELETE CARD DATA
            Configuration::deleteByName('SIBS_CC_ONECLICK')
        );

        return $deleteConfigurationResult;
    }

    // ADD VALUES

    public function addOrUpdateOrderStatus($params)
    {
        SibsLog::warning('DEBUG: addOrUpdateOrderStatus....');

        $configuration_status_id = SibsModels::getConfigurationId($params);
        $order_state_id          = null;

        if (! empty($configuration_status_id)) {
            $statusConfiguration = new \Configuration($configuration_status_id);
            $order_state_id      = $statusConfiguration->getFields()['value'];
        }

        $new = empty($order_state_id);

        $orderState              = ($new) ? new \OrderState() : new \OrderState($order_state_id);
        $orderState->name        = [];
        $orderState->module_name = $this->name;
        $orderState->send_email  = $params['send_email'];
        $orderState->color       = $params['color'];
        $orderState->hidden      = $params['hidden'];
        $orderState->delivery    = $params['delivery'];
        $orderState->logable     = $params['logable'];
        $orderState->invoice     = $params['invoice'];
        $orderState->paid        = $params['paid'];

        foreach (\Language::getLanguages() as $language) {
            $id_lang = $language['id_lang'];

            $language_iso_code = strtolower($language['iso_code']);
            $name              = isset($params['locale'][$language_iso_code]) ? $params['locale'][$language_iso_code] : $params['locale']['en'];

            $orderState->template[$id_lang] = 'payment';
            $orderState->name[$id_lang]     = $name;
        }

        $executed = ($new) ? $orderState->add() : $orderState->update();

        if ($executed) {
            $sibs_icon      = __DIR__ . '/logo.gif';
            $new_state_icon = __DIR__ . "/../../img/os/{$orderState->id}.gif";
            copy($sibs_icon, $new_state_icon);

            Configuration::updateValue($params['config_key'], (int) $orderState->id);
        } else {
            throw new SibsException('Error on create or update Order Status');
        }
    }

    public function addSibsOrderStatus()
    {
        SibsLog::warning('DEBUG: addSibsOrderStatus....');

        try {
            $this->addOrUpdateOrderStatus([
                'config_key' => SibsConstants::ORDER_STATUS_SIBS_PENDING,
                'locale'     => SibsConstants::ORDER_STATUS_SIBS_PENDING_TRANSLATIONS,
                'send_email' => false,
                'color'      => SibsConstants::ORDER_STATUS_SIBS_PENDING_COLOR,
                'hidden'     => false,
                'delivery'   => false,
                'logable'    => true,
                'invoice'    => false,
                'paid'       => false,
            ]);

            $this->addOrUpdateOrderStatus([
                'config_key' => SibsConstants::ORDER_STATUS_SIBS_AUTHORIZED,
                'locale'     => SibsConstants::ORDER_STATUS_SIBS_AUTHORIZED_TRANSLATIONS,
                'send_email' => true,
                'color'      => SibsConstants::ORDER_STATUS_SIBS_AUTHORIZED_COLOR,
                'hidden'     => false,
                'delivery'   => false,
                'logable'    => true,
                'invoice'    => false,
                'paid'       => false,
            ]);

            $this->addOrUpdateOrderStatus([
                'config_key' => SibsConstants::ORDER_STATUS_SIBS_REFUND_PENDING,
                'locale'     => SibsConstants::ORDER_STATUS_SIBS_REFUND_PENDING_TRANSLATIONS,
                'send_email' => false,
                'color'      => SibsConstants::ORDER_STATUS_SIBS_REFUND_PENDING_COLOR,
                'hidden'     => false,
                'delivery'   => false,
                'logable'    => true,
                'invoice'    => false,
                'paid'       => false,
            ]);

            return true;
        } catch (SibsException $e) {
            SibsLog::error($e->getErrorMessage());

            return false;
        }
    }

    // HOOKS

    public function hookModuleRoutes($params)
    {
        if (! $this->active) {
            return [];
        }
        SibsLog::warning('DEBUG: hookModuleRoutes....');

        // SibsLog::warning("hookModuleRoutes: " . print_r($params, true));

        return [
            'module-sibs-webhook' => [
                'rule'       => 'sibs/webhook',
                'keywords'   => [],
                'controller' => 'webhook',
                'params'     => [
                    'fc'     => 'module',
                    'module' => 'sibs',
                ],
            ],
            'module-sibs-oneclickPage'  => [
                'controller' => 'sibs/oneclickPage',
                'keywords'   => [],
                'params'     => [
                    'fc'     => 'module',
                    'module' => 'sibs',
                ],
            ],
            'module-sibs-oneclickTerms'  => [
                'controller' => 'sibs/oneclickTerms',
                'keywords'   => [],
                'params'     => [
                    'fc'     => 'module',
                    'module' => 'sibs',
                ],
            ],
        ];
    }

    public function hookDisplayTop($params)
    {
        if (! $this->active) {
            return;
        }

        // SibsLog::warning("hookDisplayTop: " . print_r($params, true));

        $sibs_error = Tools::getValue('sibs_error');

        if (! $sibs_error) {
            return false;
        }

        $errorMessage = $this->getErrorMessage($sibs_error);

        $this->context->smarty->assign([
            'error_message' => $errorMessage,
            'module'        => 'sibs',
        ]);

        SibsLog::error("sibs_error: $sibs_error");

        return $this->display(__FILE__, 'error.tpl');
    }

    public function hookHeader($params)
    {
        if (! $this->active) {
            return;
        }
        SibsLog::warning('DEBUG: hookHeader....');

        $this->context->controller->addJS('http://code.jquery.com/ui/1.13.2/jquery-ui.min.js');

        if (isset($this->context->controller->php_self) && $this->context->controller->php_self === 'order') {
            $this->context->controller->addCSS(($this->_path) . 'views/css/payment_options.css', 'all');
            $this->context->controller->addJS(($this->_path) . 'views/js/payment_options.js', 'all');
        }
        $this->context->controller->addJS(($this->_path) . 'views/js/sibs-payments.js', 'all');
    }

    public function hookPaymentOptions($params)
    {
        if (! $this->active) {
            return;
        }
        SibsLog::warning('DEBUG: hookPaymentOptions....');

        // SibsLog::warning("hookPaymentOptions: " . print_r($params, true));

        if (! $this->checkCurrency($params['cart'])) {
            return;
        }

        $paymentOptions = [];
        $paymentMethods = $this->getAvailablePaymentMethods();

        foreach ($paymentMethods as $paymentMethod) {
            switch ($paymentMethod) {
                case SibsConstants::PAYMENT_METHOD_CREDIT_CARD:
                    array_push($paymentOptions, $this->newCardPaymentOption($paymentMethod));

                    break;
                default:
                    array_push($paymentOptions, $this->newPaymentOption($paymentMethod));

                    break;
            }
        }

        return $paymentOptions;
    }

    public function hookPaymentReturn($params)
    {
        if (! $this->active) {
            return false;
        }
        SibsLog::warning('DEBUG: hookPaymentReturn....');

        // SibsLog::warning("hookPaymentReturn: " . print_r($params, true));

        $succesfulStates = [
            Configuration::get(SibsConstants::ORDER_STATUS_PAYMENT),
            Configuration::get(SibsConstants::ORDER_STATUS_SIBS_PENDING),
            Configuration::get(SibsConstants::ORDER_STATUS_SIBS_AUTHORIZED),
        ];

        $state = $params['order']->getCurrentState();
        SibsLog::info("state: $state");

        $orderId = Tools::getValue('id_order');
        SibsLog::info("orderId: $orderId");

        $order         = (array) $params['order'];
        $order_payment = $this->l($order['payment']);

        if (in_array($state, $succesfulStates)) {
            $sibsOrder = SibsModels::getOrderSibs($orderId);

            switch ($sibsOrder['payment_method']) {
                case SibsConstants::PAYMENT_METHOD_CARD:
                case SibsConstants::PAYMENT_METHOD_TOKEN:
                case SibsConstants::PAYMENT_METHOD_CREDIT_CARD:
                    $image = 'views/img/card.png';

                    break;
                case SibsConstants::PAYMENT_METHOD_BLIK:
                    $image = 'views/img/blik.png';

                    break;
                    // case SibsConstants::PAYMENT_METHOD_PAY_BY_LINK:
                case SibsConstants::PAYMENT_METHOD_PAY_BY_LINK_KEVIN:
                    $image = 'views/img/pay_by_link.png';

                    break;
                default:
                    $image = 'views/img/sibs_logo.png';
            }

            $message = $this->l('Thank you. Your order has been received and successfull paid with') . " $order_payment";
            $method  = $this->context->cookie->__get('sibs_paymentBrand');

            switch ($state) {
                case Configuration::get(SibsConstants::ORDER_STATUS_PAYMENT):
                case Configuration::get(SibsConstants::ORDER_STATUS_SIBS_AUTHORIZED):
                    $status   = $this->l('SUCCESSFUL');
                    $template = 'order_successful';

                    break;
                case Configuration::get(SibsConstants::ORDER_STATUS_SIBS_PENDING):
                    $status   = $this->l('BACKEND_CH_MODEPREAUTH');
                    $template = 'order_pa';

                    break;
                default:
                    $status   = '';
                    $template = '';
            }

            SibsLog::info("method: $method");
            SibsLog::info("status: $status");
            SibsLog::info("template: $template");

            $vars = [
                'shop_name' => $this->context->shop->name,
                'status'    => 'ok',
                'image'     => Tools::getShopDomain(true, true) . __PS_BASE_URI__ . "modules/sibs/$image",
                'message'   => $message,
            ];
        } else {
            $vars = ['status' => 'nok'];
        }

        $this->context->smarty->assign($vars);
        $this->context->cookie->__unset('sibs_paymentBrand');

        return $this->display(__FILE__, 'payment_return.tpl');
    }

    public function hookActionEmailAddAfterContent($params)
    {
        if (! $this->active) {
            return;
        }
        SibsLog::warning('DEBUG: hookActionEmailAddAfterContent....');

        // SibsLog::warning("hookActionEmailAddAfterContent: " . print_r($params, true));

        $content = '';

        if (in_array($params['template'], ['order_conf', 'order_pa'])) {
            $cookie         = (array) $params['cookie'];
            $cookie_content = $cookie["\0*\0_content"];

            SibsLog::info("template: {$params['template']}");
            SibsLog::info('cookie inside template: <pre>' . print_r($cookie_content, true) . '</pre>');

            if ($cookie_content['sibs_paymentBrand']) {
                $orderMethod = $cookie_content['sibs_paymentBrand'];
                SibsLog::info("orderMethod: $orderMethod");

                if (in_array($orderMethod, [SibsConstants::PAYMENT_METHOD_BLIK, SibsConstants::PAYMENT_METHOD_PAY_BY_LINK])) {
                    if ($orderMethod == SibsConstants::PAYMENT_METHOD_BLIK) {
                        $translatedText = $this->l('ORDER_PROCESSED_BLIK');
                    } elseif ($orderMethod == SibsConstants::PAYMENT_METHOD_PAY_BY_LINK) {
                        $translatedText = $this->l('ORDER_PROCESSED_PBL');
                    }

                    // PT: A sua encomenda será processada após pagamento com sucesso na app PBL
                    // EN: Your order will be processed after successful payment in the PBL app
                    $count = 0;
                    SibsLog::info('found: ' . substr_count($params['template_html'], '{SHOP_NAME}!'));

                    $tempContent             = "<br><span style=\"font-weight:500;font-size:12px;\">{$translatedText}</span>";
                    $params['template_html'] = str_replace(
                        '{shop_name}!',
                        "{shop_name}!$tempContent",
                        $params['template_html'],
                        $count
                    );

                    SibsLog::info("replaced: $count");
                }
            }
        }

        $params['template_html'] = str_replace('{payment}', "{payment}$content", $params['template_html']);
    }

    public function hookDisplayInvoice($params)
    {
        if (! $this->active) {
            return;
        }
        SibsLog::warning('DEBUG: hookDisplayInvoice....');

        // SibsLog::warning("hookDisplayInvoice: " . print_r($params, true));

        $order = new \Order($params['id_order']);

        $success_message = '';
        $error_message   = '';

        $continueCheck = $this->checkCookieSibsStatus($success_message, $error_message, 'capture');

        if ($continueCheck) {
            $continueCheck = $this->checkCookieSibsStatus($success_message, $error_message, 'refund');
        }

        if ($continueCheck) {
            $continueCheck = $this->checkCookieSibsStatus($success_message, $error_message, 'cancel');
        }

        if ($continueCheck) {
            $continueCheck = $this->checkCookieSibsStatus($success_message, $error_message, 'update_order');
        }

        if ($continueCheck) {
            $continueCheck = $this->checkCookieSibsStatus($success_message, null, 'new_order');
        }

        $this->context->smarty->assign([
            'module'         => (is_object($order) && isset($order->module) ? $order->module : null),
            'successMessage' => $success_message,
            'errorMessage'   => $error_message,
        ]);

        return $this->display(__FILE__, 'views/templates/hook/displayStatusOrder.tpl');
    }

    public function hookDisplayAdminOrderMain(array $params)
    {
        SibsLog::warning('DEBUG: hookDisplayAdminOrderMain....');

        $sibsOrder = SibsModels::getOrderSibsLog($params['id_order']);

        $this->context->smarty->assign([
            'order_id'  => $params['id_order'],
            'sibsOrder' => $sibsOrder,
        ]);

        return $this->context->smarty->fetch($this->getLocalPath() . 'views/templates/hook/displayAdminOrderLeft.tpl');
    }

    public function hookDisplayFooter($params)
    {
        SibsLog::warning('DEBUG: hookDisplayFooter....');

        $this->context->smarty->assign([
            'url_module'  => _MODULE_DIR_,
            'url_site'    => __PS_BASE_URI__,
        ]);

        return $this->context->smarty->fetch($this->getLocalPath() . 'views/templates/hook/displayFooter.tpl');
        // return 'Hello world';
    }

    public function hookDisplayAdminOrderSide($params)
    {
        if (! $this->active) {
            return;
        }
        SibsLog::warning('DEBUG: hookDisplayAdminOrderSide....');

        // SibsLog::warning('displayAdminOrderSide: ' . print_r($params, true));

        $orderID   = Tools::getValue('id_order');
        $sibsOrder = SibsModels::getOrderSibs($orderID);

        SibsLog::info("hookDisplayAdminOrderSide: $orderID");
        SibsLog::info("orderID: $orderID");
        SibsLog::info('sibsOrder: ' . print_r($sibsOrder, true));

        if ($sibsOrder) {
            // sibs order status
            if (Tools::isSubmit('sibsOrderStatus')) {
                SibsLog::info('sibsOrderStatus.....');
                $this->sibsOrderStatus($sibsOrder);
            }

            // sibs capture
            if (Tools::isSubmit('sibsCapture')) {
                SibsLog::info('sibsCapture.....');
                $this->sibsCapture($sibsOrder);
            }

            // sibs refund
            if (Tools::isSubmit('sibsRefund')) {
                SibsLog::info('sibsRefund.....');
                $this->sibsRefund($sibsOrder);
            }

            $this->sibsMakeContext($sibsOrder);
        }

        return $this->display(__FILE__, 'views/templates/hook/displayAdminOrder.tpl');
    }

    public function getAddress($address)
    {
        SibsLog::warning('DEBUG: getAddress....');

        if (is_numeric($address)) {
            $address = new Address($address);
        }

        if ($address instanceof Address) {
            return $address;
        }

        return null;
    }

    public function hookActionValidateCustomerAddressForm($params)
    {
        if (! $this->active) {
            return;
        }
        SibsLog::warning('DEBUG: hookActionValidateCustomerAddressForm....');

        /* Here is the triggered hook */
        $customer        = new Customer($params['cart']->id_customer);
        $customerAddress = ['customer' => $customer, 'cart' => $params['cart']];

        $module = Module::getInstanceByName('sibs');

        $is_valid     = true;
        $form         = $params['form'];
        $id_address   = (isset($params['cart']->id_address_invoice)) ? $params['cart']->id_address_invoice : ((isset($params['cart']->id_address_delivery)) ? $params['cart']->id_address_delivery : null);
        $address      = $this->getAddress($id_address);
        $postcode     = '' . $address->postcode ?? null;
        $countryCode  = $form->getField('id_country')->getValue();

        if (! empty($postcode)) {
            if (is_numeric($countryCode)) {
                $validator_country = new Country($countryCode);
                $countryCode       = Country::getZipCodeFormat($countryCode);
                $validator         =  $validator_country->checkZipCode($postcode);

                if ($validator == false) {
                    $params->addError($form->translator->trans(
                        'Invalid postcode - should look like "%zipcode%"',
                        ['%zipcode%' => $validator_country->zip_code_format],
                        'Shop.Forms.Errors'
                    ));
                }
            }
        }

        $address1       = $form->getField('address1');
        $address2       = $form->getField('address2');
        $address1_chars = strlen($form->getValue('address1'));
        $address2_chars = strlen($form->getValue('address2'));
        $total_char     = $address1_chars + $address2_chars;
        SibsLog::warning('total_char: ' . json_encode($total_char, true));

        if ($total_char > 70) {
            $address1->addError($module->l('ERROR_CHARS'));
            $address2->addError($module->l('ERROR_CHARS'));
        }

        //return $this->hookActionCustomerAccountUpdate($customerAddress);
        SibsLog::warning('hookActionValidateCustomerAddressForm: ' . json_encode($params, true));
        // SibsLog::warning('hookActionValidateCustomerAddressForm:  is_valid' . var_dump($is_valid));
        SibsLog::warning('hookActionValidateCustomerAddressForm: ' . json_encode($customerAddress, true));
    }

    public function hookActionProductCancel($params)
    {
        if (! $this->active) {
            return;
        }
        SibsLog::warning('DEBUG: hookActionProductCancel....');

        // SibsLog::warning("hookActionProductCancel: " . print_r($params, true));

        switch ($params['action']) {
            case CancellationActionType::STANDARD_REFUND:
                SibsLog::info('STANDARD_REFUND');

                break;
            case CancellationActionType::RETURN_PRODUCT:
                SibsLog::info('RETURN_PRODUCT');

                break;
            case CancellationActionType::PARTIAL_REFUND:
                SibsLog::info('PARTIAL_REFUND');
                $getOrderSibs = SibsModels::getOrderSibs($params['order']->id);
                $sibsOrder    = new \Order($params['order']->id);

                SibsLog::warning('hookActionProductCancel: sibsOrder ' . json_encode($sibsOrder, true));

                $this->sibsRefundParcial($getOrderSibs, $sibsOrder, $params);

                break;
            case CancellationActionType::CANCEL_PRODUCT:
                SibsLog::info('CANCEL_PRODUCT');

                break;
        }
    }

    public function hookActionOrderSlipAdd($params)
    {
        if (! $this->active) {
            return;
        }
        SibsLog::warning('DEBUG: hookActionOrderSlipAdd....');

        // SibsLog::warning("actionOrderSlipAdd: " . print_r($params, true));

        $order_slips = \OrderSlip::getOrdersSlip((int) $params['order']->id_customer, (int) $params['order']->id);

        foreach ($order_slips as $order_slip_details) {
            $order_slip = new \OrderSlip((int) $order_slip_details['id_order_slip']);
            /* Your actions. */
        }
    }

    public function hookActionPaymentCCAdd($params)
    {
        if (! $this->active) {
            return;
        }
        SibsLog::warning('DEBUG: hookActionPaymentCCAdd....');

        // SibsLog::warning("hookActionPaymentCCAdd: " . print_r($params, true));
    }

    // OTHER FUNCTIONS

    public function newPaymentOption($paymentMethod)
    {
        SibsLog::warning('DEBUG: newPaymentOption....');

        $lowercasePaymentMethod = Tools::strtolower($paymentMethod);
        $paymentController      = $this->context->link->getModuleLink(
            $this->name,
            "payment{$lowercasePaymentMethod}",
            [],
            true
        );

        $logo     = "{$lowercasePaymentMethod}.png";
        $logoPath = Media::getMediaPath(_PS_MODULE_DIR_ . "{$this->name}/views/img/$logo");

        $newPaymentOption = new PaymentOption();
        $paymentForm      = $this->fetch('module:sibs/views/templates/hook/payment_options.tpl');
        $newPaymentOption->setCallToActionText($this->l('FRONTEND_MC_' . $paymentMethod))
            ->setLogo($logoPath)
            ->setModuleName($this->name)
            ->setForm($paymentForm)
            ->setAction($paymentController);

        return $newPaymentOption;
    }

    public function newCardPaymentOption($cardPaymentMethod)
    {
        SibsLog::warning('DEBUG: newCardPaymentOption....');

        $oneclick = Configuration::get('SIBS_CC_ONECLICK');

        $lowercasePaymentMethod = Tools::strtolower($cardPaymentMethod);
        $paymentController      = $this->context->link->getModuleLink(
            $this->name,
            "payment{$lowercasePaymentMethod}",
            [],
            true
        );

        $newCardPaymentOption = new PaymentOption();

        $ccBrands = explode(',', Configuration::get("SIBS_{$cardPaymentMethod}_CARDS"));

        if (! empty($ccBrands)) {
            $lowercaseCcBrand_0 = Tools::strtolower($ccBrands[0]);
            $logo               = "{$lowercaseCcBrand_0}.png";
            $logoPath           = Media::getMediaPath(_PS_MODULE_DIR_ . "{$this->name}/views/img/$logo");

            $hiddenLogos = '';
            foreach ($ccBrands as $key => $ccBrand) {
                $lowercaseCcBrand = Tools::strtolower($ccBrand);
                $hiddenLogo       = "{$lowercaseCcBrand}.png";
                $hiddenLogoPath   = Media::getMediaPath(_PS_MODULE_DIR_ . "{$this->name}/views/img/$hiddenLogo");
                $hiddenLogos .= "<input type=\"hidden\" id=\"cc_brand_{$key}\" value=\"$hiddenLogoPath\">";
            }

            $newCardPaymentOption->setCallToActionText($this->l('FRONTEND_MC_CC'))
                ->setLogo($logoPath)
                ->setAdditionalInformation($hiddenLogos)
                ->setAction($paymentController);

            if ($this->context->customer->isLogged() && $oneclick === SibsConstants::SIBS_TOKEN_ONECLICK) {
                $oneclickPaymentForm = $this->getOneclickForm($paymentController);
                $newCardPaymentOption->setForm($oneclickPaymentForm);
            }
        }

        return $newCardPaymentOption;
    }

     public function getOneclickPDFTermsByLanguage()
     {
         SibsLog::warning('DEBUG: getOneclickPDFTermsByLanguage....');

         // Update from: https://www.pay.sibs.com/eng/documentation/sibs-gateway-3/files/20220713_End%20customer%20regulations%20PL_KK_PS_PDF.pdf/
         // Update from: https://www.pay.sibs.com/eng/documentation/sibs-gateway-3/files/20220713_End%20customer%20regulations%20PL_KK_PS%20en-US_PDF.pdf/

         $iso_code = Context::getContext()->language->iso_code;

         switch($iso_code) {
             case 'pl':
             case 'en':
                 return "sibs_terms_and_conditions_{$iso_code}.pdf";

                 break;
             default:
                 return 'sibs_terms_and_conditions_en.pdf';
         }
     }

    public function getOneclickForm($paymentController)
    {
        SibsLog::warning('DEBUG: getOneclickForm....');

        $pdf        = $this->getOneclickPDFTermsByLanguage();
        $siteUrl    = str_replace('/shop', '', (Tools::getHttpHost(true) . __PS_BASE_URI__));
        $pdfMedia   = "modules/sibs/views/files/$pdf";
        $embedMedia = "{$siteUrl}{$pdfMedia}";

        // $sibsTermsAndConditionsLink    = $this->getTermsAndConditionsLink();
        $sibsTermsAndConditionsLabel   = $this->l('SIBS terms of service');
        $sibsTermsAndConditionsTagLink = '
            <div style="display:none" id="dialog" title="' . $this->l('OneClick Definition Page') . '">
                <p>' .
                    $this->l('If you activate OneClick, we will verify your card and you will see a transaction for 0 PLN on your account.') .
                    $this->l('Please note that your bank may require additional authorization.') .
                '</p>
                <p>' .
                    $this->l('With OneClick activated, we will not ask you to enter your card details for future payments.') .
                '</p>
            </div>
            <div style="display:none" id="dialog2" title="' . $this->l('SIBS terms of service') . '">
                <embed src="' . $embedMedia . '" frameborder="0" width="100%" style="float:left; position:relative; height:100%;">
            </div>
            <span onclick="$(\'#dialog2\').dialog({ height: 400, width:600});" id="cta-terms-and-conditions-sibs" 
                style="color:#24b9d7; text-decoration:none; cursor:pointer;">
                ' . $sibsTermsAndConditionsLabel . '
            </span>';

        // $oneclickLink    = $this->getOneclickLink();
        $oneclickLabel   = $this->l('OneClick');
        $oneclickTagLink = '
        <span onclick="$(\'#dialog\').dialog({ height: 400, width:600});" id="cta-oneclick-sibs"
            style="color:#24b9d7; text-decoration:none; cursor:pointer;">
            ' . $oneclickLabel . '
        </span>';

        $customerAcceptorLabel = sprintf(
            $this->l('I agree to the %s and will adhere to them unconditionally for %s payment.'),
            $sibsTermsAndConditionsTagLink,
            $oneclickTagLink
        );

        $oneclickPaymentForm = "
        <form action=\"$paymentController\" method=\"post\" style=\"padding-bottom:10px\">
            <div class=\"float-xs-left\">
                <span class=\"custom-checkbox\">
                    <input type=\"checkbox\" id=\"sibsCustomerAcceptor\" name=\"sibsCustomerAcceptor\" class=\"ps-shown-by-js\">
                    <span><i class=\"material-icons rtl-no-flip checkbox-checked\"></i></span>
                </span>
            </div>
            <div class=\"condition-label\">
                <label class=\"js-terms\" for=\"sibsCustomerAcceptor\">
                    $customerAcceptorLabel
                </label>
            </div>
        </form>";

        return $oneclickPaymentForm;
    }

    public function getTermsAndConditionsLink()
    {
        return $this->context->link->getModuleLink('sibs', 'oneclickTerms', [], true);
    }

    public function getOneclickLink()
    {
        return $this->context->link->getModuleLink('sibs', 'oneclickPage', [], true);
    }

    public function checkCookieSibsStatus(&$success_message, &$error_message, $status)
    {
        SibsLog::warning('DEBUG: checkCookieSibsStatus....');

        $cookieIsSet = $this->context->cookie->__isset("sibs_status_{$status}");

        if ($cookieIsSet) {
            if ($this->context->cookie->__get("sibs_status_{$status}")) {
                $success_message = $status;
            } else {
                $error_message = $status;
            }
        }

        $this->context->cookie->__unset("sibs_status_{$status}");

        return $cookieIsSet;
    }

    public function checkCurrency($cart)
    {
        SibsLog::warning('DEBUG: checkCurrency....');

        $currencyOrder   = new \Currency($cart->id_currency);
        $currencyModules = $this->getCurrency($cart->id_currency);

        if (is_array($currencyModules)) {
            foreach ($currencyModules as $currencyModule) {
                if ($currencyOrder->id == $currencyModule['id_currency']) {
                    return true;
                }
            }
        }

        return false;
    }

    private function getAvailablePaymentMethods()
    {
        SibsLog::warning('DEBUG: getAvailablePaymentMethods....');

        $paymentMethods = $this->payment_methods;
        $toSub          = null;

        //Acesso à db que corrige todos os estados pending (código 15)
        $toSub['template'] = 'order_pa';
        $toSub['name']     = 'Pagamento Pendente';

        $sortedPaymentMethods = [];
        foreach ($paymentMethods as $paymentMethod) {
            if (Configuration::get("SIBS_{$paymentMethod}_ACTIVE")) {
                if (in_array($paymentMethod, $this->card_payment_methods)) {
                    if (trim(Configuration::get("SIBS_{$paymentMethod}_CARDS"))) {
                        $sortedPaymentMethods[$paymentMethod] = Configuration::get("SIBS_{$paymentMethod}_SORT");
                    }
                } else {
                    $sortedPaymentMethods[$paymentMethod] = Configuration::get("SIBS_{$paymentMethod}_SORT");
                }
            }
        }

        $keys   = array_keys($sortedPaymentMethods);
        $values = array_values($sortedPaymentMethods);
        array_multisort($values, $keys);

        return $keys;
    }

    public static function getVersionData()
    {
        SibsLog::warning('DEBUG: getVersionData....');

        $versionData = [];

        try {
            if (isset($_SERVER['SERVER_ADDR'])) {
                $versionData['ip_address'] = $_SERVER['SERVER_ADDR'];
            } elseif (isset($_SERVER['LOCAL_ADDR'])) {
                $versionData['ip_address'] = $_SERVER['LOCAL_ADDR'];
            } else {
                $versionData['ip_address'] = gethostbyname($_SERVER['SERVER_NAME']);
            }
        } catch (Exception $e) {
            $versionData['ip_address'] = '127.0.0.1';
        }

        $versionData['shop_version'] = _PS_VERSION_;
        $versionData['client']       = SibsConstants::SIBS_DISPLAY_NAME;
        $versionData['email']        = Configuration::get('SIBS_GENERAL_CLIENTID');
        $versionData['terminalid']   = Configuration::get('SIBS_GENERAL_TERMINALID');
        $versionData['bearer']       = Configuration::get('SIBS_GENERAL_BEARER');
        $versionData['shop_system']  = SibsConstants::SIBS_SHOP_SYSTEM;

        return $versionData;
    }

    private function validateConfigurationPost()
    {
        SibsLog::warning('DEBUG: validateConfigurationPost....');

        if (Tools::isSubmit('btnSubmit')) {
            $isRequired     = false;
            $fieldsRequired = [];

            if (empty(trim(Tools::getValue('SIBS_GENERAL_CLIENTID')))) {
                $fieldsRequired[] = ($this->l('BACKEND_GENERAL_CLIENTID') !== 'BACKEND_GENERAL_CLIENTID') ?
                    $this->l('BACKEND_GENERAL_CLIENTID') :
                    'Merchant Email';

                $isRequired = true;
            }

            if (empty(trim(Tools::getValue('SIBS_GENERAL_TERMINALID')))) {
                $fieldsRequired[] = ($this->l('BACKEND_GENERAL_TERMINALID') !== 'BACKEND_GENERAL_TERMINALID') ?
                    $this->l('BACKEND_GENERAL_TERMINALID') :
                    'Terminal ID';

                $isRequired = true;
            }

            if (empty(trim(Tools::getValue('SIBS_GENERAL_BEARER')))) {
                $fieldsRequired[] = ($this->l('BACKEND_GENERAL_BEARER') !== 'BACKEND_GENERAL_BEARER') ?
                    $this->l('BACKEND_GENERAL_BEARER') :
                    'Bearer Token';

                $isRequired = true;
            }

            if ($isRequired) {
                $warning = implode(', ', $fieldsRequired) . ' ';

                $warning .= ($this->l('ERROR_MANDATORY') !== 'ERROR_MANDATORY') ?
                    $this->l('ERROR_MANDATORY') :
                    'is required. please fill out this field';

                $this->html .= $this->displayWarning($warning);
            } else {
                $this->configurationPost();
            }
        }
    }

    private function configurationPost()
    {
        SibsLog::warning('DEBUG: configurationPost....');

        Configuration::updateValue(
            'SIBS_GENERAL_CLIENTID',
            Tools::getValue('SIBS_GENERAL_CLIENTID')
        );

        Configuration::updateValue(
            'SIBS_GENERAL_TERMINALID',
            Tools::getValue('SIBS_GENERAL_TERMINALID')
        );

        Configuration::updateValue(
            'SIBS_GENERAL_BEARER',
            Tools::getValue('SIBS_GENERAL_BEARER')
        );

        Configuration::updateValue(
            'SIBS_WEBHOOK_SECRET',
            Tools::getValue('SIBS_WEBHOOK_SECRET')
        );

        Configuration::updateValue(
            'SIBS_GENERAL_ENVIRONMENT',
            Tools::getValue('SIBS_GENERAL_ENVIRONMENT')
        );

        foreach ($this->payment_methods as $value) {
            Configuration::updateValue(
                "SIBS_{$value}_ACTIVE",
                Tools::getValue("SIBS_{$value}_ACTIVE")
            );

            // debit/authorization methods
            if (in_array($value, $this->db_pa_payment_methods)) {
                Configuration::updateValue(
                    "SIBS_{$value}_MODE",
                    Tools::getValue("SIBS_{$value}_MODE")
                );
            }

            Configuration::updateValue(
                "SIBS_{$value}_SORT",
                Tools::getValue("SIBS_{$value}_SORT")
            );

            // card payment methods
            if (in_array($value, $this->card_payment_methods)) {
                $cards       = Tools::getValue("SIBS_{$value}_CARDS");
                $multiSelect = is_array($cards) ? implode(',', $cards) : '';

                Configuration::updateValue(
                    "SIBS_{$value}_CARDS",
                    $multiSelect
                );
            }

            // credit card method
            if ($value == SibsConstants::PAYMENT_METHOD_CREDIT_CARD) {
                Configuration::updateValue(
                    "SIBS_{$value}_ONECLICK",
                    Tools::getValue("SIBS_{$value}_ONECLICK")
                );
            }

            // pay by link method
            if ($value == SibsConstants::PAYMENT_METHOD_PAY_BY_LINK) {
                Configuration::updateValue(
                    "SIBS_{$value}_EXPIRATION_PAYMENT_TYPE",
                    Tools::getValue("SIBS_{$value}_EXPIRATION_PAYMENT_TYPE")
                );

                Configuration::updateValue(
                    "SIBS_{$value}_EXPIRATION_PAYMENT_VALUE",
                    Tools::getValue("SIBS_{$value}_EXPIRATION_PAYMENT_VALUE")
                );
            }

            // blik method
            if ($value == SibsConstants::PAYMENT_METHOD_BLIK) {
                Configuration::updateValue(
                    "SIBS_{$value}_NUMBER_OF_RETRIES_VALUE",
                    Tools::getValue("SIBS_{$value}_NUMBER_OF_RETRIES_VALUE")
                );

                Configuration::updateValue(
                    "SIBS_{$value}_DELAY_BETWEEN_RETRIES_VALUE",
                    Tools::getValue("SIBS_{$value}_DELAY_BETWEEN_RETRIES_VALUE")
                );
            }
        }

        $chUpdated = $this->l('BACKEND_CH_UPDATED') !== 'BACKEND_CH_UPDATED' ?
            $this->l('BACKEND_CH_UPDATED') :
            'Debit';

        $this->html .= $this->displayConfirmation($chUpdated);
    }

    public function getContent()
    {
        SibsLog::warning('DEBUG: getContent....');

        if (Tools::isSubmit('btnSubmit')) {
            $this->validateConfigurationPost();
        } elseif (Configuration::get('SIBS_POPUP')) {
            // removido temporariamente.
            //  $popUpInfo = $this->context->smarty->fetch("{$this->local_path}views/templates/admin/popUpInfo.tpl");
            //  $this->html .= $popUpInfo;

            Configuration::updateValue('SIBS_POPUP', false);
        } else {
            $this->html .= '<br/>';
        }

        $this->html .= $this->renderReportingField();
        $this->html .= $this->renderForm();

        return $this->html;
    }

    protected function renderReportingField()
    {
        SibsLog::warning('DEBUG: renderReportingField....');

        $shopDomainSsl   = Tools::getShopDomainSsl(true, true);
        $backOfficeJsUrl = $shopDomainSsl . __PS_BASE_URI__ . "modules/{$this->name}/views/js/backoffice.js";
        $reportLocale    = $this->getReportLocale();

        $tplVars = [
            'title'           => $reportLocale['raisingIssue'],
            'reportLabel'     => $reportLocale['report'],
            'backOfficeJsUrl' => $backOfficeJsUrl,
        ];

        $this->context->smarty->assign($tplVars);

        return $this->display(__FILE__, 'views/templates/admin/reporting.tpl');
    }

    public function renderForm()
    {
        SibsLog::warning('DEBUG: renderForm....');

        $locale = $this->getLocaleForm();

        $generalForm = $this->getGeneralForm($locale);
        $paymentForm = $this->getPaymentForm($locale);
        $fieldsForm  = array_merge($generalForm, $paymentForm);

        $helper                        = new \HelperForm();
        $helper->show_toolbar          = false;
        $helper->table                 = $this->table;
        $lang                          = new Language((int) Configuration::get('PS_LANG_DEFAULT'));
        $helper->default_form_language = $lang->id;

        $helper->allow_employee_form_lang = (! empty(Configuration::get('PS_BO_ALLOW_EMPLOYEE_FORM_LANG'))) ?
            Configuration::get('PS_BO_ALLOW_EMPLOYEE_FORM_LANG') :
            0;

        $this->fields_form     = [];
        $this->fields_form     = $fieldsForm;
        $helper->id            = (int) Tools::getValue('id_carrier');
        $helper->identifier    = $this->identifier;
        $helper->submit_action = 'btnSubmit';
        $helper->currentIndex  = $this->context->link->getAdminLink(
            'AdminModules',
            false
        ) . "&configure={$this->name}&tab_module={$this->tab}&module_name={$this->name}";
        $helper->token    = Tools::getAdminTokenLite('AdminModules');
        $helper->tpl_vars = [
            'fields_value' => $this->getConfigFieldsValues(),
            'languages'    => $this->context->controller->getLanguages(),
            'id_language'  => $this->context->language->id,
            'css'          => $this->context->controller->addCSS(($this->_path) . 'views/css/payment_options.css', 'all'),
        ];

        return $helper->generateForm($this->fields_form);
    }

    private function getReportLocale()
    {
        SibsLog::warning('DEBUG: getReportLocale....');

        $locale = [];

        $locale['raisingIssue'] = ($this->l('SIBS_BACKEND_RAISING_ISSUE') !== 'SIBS_BACKEND_RAISING_ISSUE') ?
            $this->l('SIBS_BACKEND_RAISING_ISSUE') :
            'Raise an Issue';

        $locale['report'] = ($this->l('BACKEND_GENERAL_REPORT') !== 'BACKEND_GENERAL_REPORT') ?
            $this->l('BACKEND_GENERAL_REPORT') :
            'Report feedback';

        return $locale;
    }

    private function getLocaleForm()
    {
        SibsLog::warning('DEBUG: getLocaleForm....');

        $locale = [];

        $locale['recurring']['label'] = ($this->l('BACKEND_GENERAL_RECURRING') !== 'BACKEND_GENERAL_RECURRING') ?
            $this->l('BACKEND_GENERAL_RECURRING') :
            'Recurring';

        $locale['clientid']['label'] = ($this->l('BACKEND_GENERAL_CLIENTID') !== 'BACKEND_GENERAL_CLIENTID') ?
            $this->l('BACKEND_GENERAL_CLIENTID') :
            'Client ID';

        $locale['terminalid']['label'] = ($this->l('BACKEND_GENERAL_TERMINALID') !== 'BACKEND_GENERAL_TERMINALID') ?
            $this->l('BACKEND_GENERAL_TERMINALID') :
            'Terminal ID';

        $locale['terminalid']['desc'] = ($this->l('BACKEND_TT_MERCHANT_ID') !== 'BACKEND_TT_MERCHANT_ID') ?
            $this->l('BACKEND_TT_MERCHANT_ID') :
            'Your Customer ID from SIBS.';

        $locale['bearer']['label'] = ($this->l('BACKEND_GENERAL_BEARER') !== 'BACKEND_GENERAL_BEARER') ?
            $this->l('BACKEND_GENERAL_BEARER') :
            'Bearer Token';

        $locale['webhook_secret']['label'] = ($this->l('BACKEND_WEBHOOK_SECRET') !== 'BACKEND_WEBHOOK_SECRET') ?
            $this->l('BACKEND_WEBHOOK_SECRET') :
            'SIBS WebHook Secret';

        $locale['sibs_environment']['label'] = ($this->l('BACKEND_GENERAL_ENVIRONMENT') !== 'BACKEND_GENERAL_ENVIRONMENT') ?
            $this->l('BACKEND_GENERAL_ENVIRONMENT') :
            'SIBS Environment';

        $PHPSodiumAvailable = false;
        $PHPSodiumVersion   = $this->l(
            'We have detected that you [red]do not have Libsodium available[/red]
            which will not be able to run SiBS’ asynchronous
            notifications.
            Please install a version of PHP greater or equal than 7.2'
        );

        if (function_exists('sodium_crypto_aead_aes256gcm_is_available')) {
            if (sodium_crypto_aead_aes256gcm_is_available()) {
                $PHPSodiumAvailable = 1;
                $PHPSodiumVersion   = $this->l(
                    'We have detected that you have [green]Libsodium[/green]
                    which will be able to run the SiBS’ asynchronous
                    notifications.'
                );
            }
        }

        if (! $PHPSodiumAvailable) {
            $dir = str_replace('sibs.php', '', __DIR__) .
                DIRECTORY_SEPARATOR . 'controllers' .
                DIRECTORY_SEPARATOR . 'front' .
                DIRECTORY_SEPARATOR . 'vendor' .
                DIRECTORY_SEPARATOR . 'sodium_compat-1.7.0' .
                DIRECTORY_SEPARATOR . 'autoload.php';
            SibsLog::info("webhook sodium dir: $dir");

            require_once $dir;

            if (function_exists('\Sodium\crypto_aead_aes256gcm_is_available')) {
                if (\Sodium\crypto_aead_aes256gcm_is_available()) {
                    SibsLog::info("webhook sodium Compact On $dir");

                    $PHPSodiumVersion = $this->l(
                        'We have detected that you have [green]Sodium compact[/green]
                        which will be able to run the SiBS’ asynchronous notifications.'
                    );
                }
            }
        }

        if (! isset($locale['webhook_secret']['desc'])) {
            $locale['webhook_secret']['desc'] = '';
        }

        $locale['webhook_secret']['desc'] .= str_replace(
            ['[br]', '[green]', '[/green]', '[red]', '[/red]'],
            [
                '<br>',
                '<font color="green">',
                '</font>',
                '<font color="red">',
                '</font>',
            ],
            $PHPSodiumVersion
        );

        $locale['cc'] = ($this->l('BACKEND_PM_CC') !== 'BACKEND_PM_CC') ?
            $this->l('BACKEND_PM_CC') :
            'Credit Cards';

        $locale['general'] = ($this->l('BACKEND_CH_GENERAL') !== 'BACKEND_CH_GENERAL') ?
            $this->l('BACKEND_CH_GENERAL') :
            'General Setting';

        $locale['ccsaved'] = ($this->l('BACKEND_PM_CCSAVED') !== 'BACKEND_PM_CCSAVED') ?
            $this->l('BACKEND_PM_CCSAVED') :
            'Credit Cards (Recurring)';

        $locale['dc'] = ($this->l('BACKEND_PM_DC') !== 'BACKEND_PM_DC') ?
            $this->l('BACKEND_PM_DC') :
            'Debit Cards';

        $locale['dd'] = ($this->l('BACKEND_PM_DD') !== 'BACKEND_PM_DD') ?
            $this->l('BACKEND_PM_DD') :
            'Direct Debit';

        $locale['ddsaved'] = ($this->l('BACKEND_PM_DDSAVED') !== 'BACKEND_PM_DDSAVED') ?
            $this->l('BACKEND_PM_DDSAVED') :
            'Direct Debit (Recurring)';

        $locale['eps'] = ($this->l('BACKEND_PM_EPS') !== 'BACKEND_PM_EPS') ?
            $this->l('BACKEND_PM_EPS') :
            'eps';

        $locale['giropay'] = ($this->l('BACKEND_PM_GIROPAY') !== 'BACKEND_PM_GIROPAY') ?
            $this->l('BACKEND_PM_GIROPAY') :
            'Giropay';

        $locale['ideal'] = ($this->l('BACKEND_PM_IDEAL') !== 'BACKEND_PM_IDEAL') ?
            $this->l('BACKEND_PM_IDEAL') :
            'iDeal';

        $locale['paypal'] = ($this->l('BACKEND_PM_PAYPAL') !== 'BACKEND_PM_PAYPAL') ?
            $this->l('BACKEND_PM_PAYPAL') :
            'PayPal';

        $locale['paydirekt'] = ($this->l('BACKEND_PM_PAYDIREKT') !== 'BACKEND_PM_PAYDIREKT') ?
            $this->l('BACKEND_PM_PAYDIREKT') :
            'paydirekt';

        $locale['easycredit'] = ($this->l('BACKEND_PM_EASYCREDIT') !== 'BACKEND_PM_EASYCREDIT') ?
            $this->l('BACKEND_PM_EASYCREDIT') :
            'easycredit';

        $locale['paypalsaved'] = ($this->l('BACKEND_PM_PAYPALSAVED') !== 'BACKEND_PM_PAYPALSAVED') ?
            $this->l('BACKEND_PM_PAYPALSAVED') :
            'PayPal (Recurring)';

        $locale['sue'] = ($this->l('BACKEND_PM_SOFORT') !== 'BACKEND_PM_SOFORT') ?
            $this->l('BACKEND_PM_SOFORT') :
            'SOFORT Banking';

        $locale['blik'] = ($this->l('BACKEND_PM_BLIK') !== 'BACKEND_PM_BLIK') ?
            $this->l('BACKEND_PM_BLIK') :
            'BLIK';

        $locale['pay_by_link'] = ($this->l('BACKEND_PM_PBL') !== 'BACKEND_PM_PBL') ?
            $this->l('BACKEND_PM_PBL') :
            'PAY_BY_LINK';

        $locale['mode']['label'] = ($this->l('BACKEND_CH_MODE') !== 'BACKEND_CH_MODE') ?
            $this->l('BACKEND_CH_MODE') :
            'Transaction-Mode';

        $locale['mode']['db'] = ($this->l('BACKEND_CH_MODEDEBIT') !== 'BACKEND_CH_MODEDEBIT') ?
            $this->l('BACKEND_CH_MODEDEBIT') :
            'Debit';

        $locale['mode']['pa'] = ($this->l('BACKEND_CH_MODEPREAUTH') !== 'BACKEND_CH_MODEPREAUTH') ?
            $this->l('BACKEND_CH_MODEPREAUTH') :
            'Pending';

        $locale['cardtype']['label'] = ($this->l('BACKEND_CH_CARDS') !== 'BACKEND_CH_CARDS') ?
            $this->l('BACKEND_CH_CARDS') :
            'Cards Types';

        $locale['cardtype']['desc'] = $this->l(
            'Hold Ctrl while selecting
            the card you want to activate the payment gateway for the selected card.'
        );

        $locale['cardtype']['visa'] = ($this->l('BACKEND_CC_VISA') !== 'BACKEND_CC_VISA') ?
            $this->l('BACKEND_CC_VISA') :
            'VISA';

        $locale['cardtype']['master'] = ($this->l('BACKEND_CC_MASTER') !== 'BACKEND_CC_MASTER') ?
            $this->l('BACKEND_CC_MASTER') :
            'MASTER';

        $locale['cardtype']['amex'] = ($this->l('BACKEND_CC_AMEX') !== 'BACKEND_CC_AMEX') ?
            $this->l('BACKEND_CC_AMEX') :
            'AMEX';

        $locale['cardtype']['diners'] = ($this->l('BACKEND_CC_DINERS') !== 'BACKEND_CC_DINERS') ?
            $this->l('BACKEND_CC_DINERS') :
            'DINERS';

        $locale['cardtype']['jcb'] = ($this->l('BACKEND_CC_JCB') !== 'BACKEND_CC_JCB') ?
            $this->l('BACKEND_CC_JCB') :
            'JCB';

        $locale['cardtype']['vpay'] = ($this->l('BACKEND_CC_VPAY') !== 'BACKEND_CC_VPAY') ?
            $this->l('BACKEND_CC_VPAY') :
            'VPAY';

        $locale['cardtype']['maestro'] = ($this->l('BACKEND_CC_MAESTRO') !== 'BACKEND_CC_MAESTRO') ?
            $this->l('BACKEND_CC_MAESTRO') :
            'MAESTRO';

        $locale['cardtype']['dankort'] = ($this->l('BACKEND_CC_DANKORT') !== 'BACKEND_CC_DANKORT') ?
            $this->l('BACKEND_CC_DANKORT') :
            'DANKORT';

        $locale['cardtype']['visaelectron'] = ($this->l('BACKEND_CC_VISAELECTRON') !== 'BACKEND_CC_VISAELECTRON') ?
            $this->l('BACKEND_CC_VISAELECTRON') :
            'VISAELECTRON';

        $locale['cardtype']['postepay'] = ($this->l('BACKEND_CC_POSTEPAY') !== 'BACKEND_CC_POSTEPAY') ?
            $this->l('BACKEND_CC_POSTEPAY') :
            'POSTEPAY';

        $locale['cardtype']['masterdebit'] = ($this->l('BACKEND_CC_MASTERDEBIT') !== 'BACKEND_CC_MASTERDEBIT') ?
            $this->l('BACKEND_CC_MASTERDEBIT') :
            'MASTERDEBIT';

        $locale['cardtype']['visadebit'] = ($this->l('BACKEND_CC_VISADEBIT') !== 'BACKEND_CC_VISADEBIT') ?
            $this->l('BACKEND_CC_VISADEBIT') :
            'VISADEBIT';

        $locale['amount']['label'] = ($this->l('BACKEND_CH_AMOUNT') !== 'BACKEND_CH_AMOUNT') ?
            $this->l('BACKEND_CH_AMOUNT') :
            'Amount for Registration';

        $locale['amount']['desc'] = ($this->l('BACKEND_TT_REGISTRATION_AMOUNT') !== 'BACKEND_TT_REGISTRATION_AMOUNT') ?
            $this->l('BACKEND_TT_REGISTRATION_AMOUNT') :
            'Amount that is debited and refunded when a shopper
             registers a payment method without purchase.';

        $locale['active']['label'] = ($this->l('BACKEND_CH_ACTIVE') !== 'BACKEND_CH_ACTIVE') ?
            $this->l('BACKEND_CH_ACTIVE') :
            'Enabled';

        $locale['multichannel']['label'] = ($this->l('BACKEND_CH_MULTICHANNEL') !== 'BACKEND_CH_MULTICHANNEL') ?
            $this->l('BACKEND_CH_MULTICHANNEL') :
            'Multichannel';

        $locale['multichannel']['desc'] = ($this->l('BACKEND_TT_MULTICHANNEL') !== 'BACKEND_TT_MULTICHANNEL') ?
            $this->l('BACKEND_TT_MULTICHANNEL') :
            'If activated, repeated recurring payments
            are handled by the alternative channel.';

        $locale['minimum_age']['label'] = ($this->l('BACKEND_CH_MINIMUM_AGE') !== 'BACKEND_CH_MINIMUM_AGE') ?
            $this->l('BACKEND_CH_MINIMUM_AGE') :
            'Minimum Age';

        $locale['payment_is_partial']['label'] = ($this->l('BACKEND_CH_PAYMENT_IS_PARTIAL') !== 'BACKEND_CH_PAYMENT_IS_PARTIAL') ?
            $this->l('BACKEND_CH_PAYMENT_IS_PARTIAL') :
            'Partial Capture or Refund';

        $locale['channelmoto']['label'] = ($this->l('BACKEND_CH_CHANNELMOTO') !== 'BACKEND_CH_CHANNELMOTO') ?
            $this->l('BACKEND_CH_CHANNELMOTO') :
            'Entity-ID MOTO';

        $locale['channelmoto']['desc'] = ($this->l('BACKEND_TT_CHANNEL_MOTO') !== 'BACKEND_TT_CHANNEL_MOTO') ?
            $this->l('BACKEND_TT_CHANNEL_MOTO') :
            'Alternative channel for recurring payments
            if Multichannel is activated (to bypass 3D Secure).';

        $locale['order']['label'] = ($this->l('BACKEND_CH_ORDER') !== 'BACKEND_CH_ORDER') ?
            $this->l('BACKEND_CH_ORDER') :
            'Sort Order';

        $locale['save'] = ($this->l('BACKEND_CH_SAVE') !== 'BACKEND_CH_SAVE') ?
            $this->l('BACKEND_CH_SAVE') :
            'Save';

        // Pay By Link  Expiration Date
        $locale['payment_expiration_value']['label'] = $this->l('Expiration Value');
        $locale['payment_expiration_type']['label']  = $this->l('Expiration Type');

        $locale['payment_expiration_type']['minute'] = $this->l('Minute');
        $locale['payment_expiration_type']['hour']   = $this->l('Hour');
        $locale['payment_expiration_type']['day']    = $this->l('Day');
        $locale['payment_expiration_type']['month']  = $this->l('Month');

        $locale['number_of_retries']['label']     = $this->l('SIBS Blik Number of Retries');
        $locale['delay_between_retries']['label'] = $this->l('SIBS Blik Retry Delay (seconds)');

        //Webhook URL
        $ShopUrl = Tools::getHttpHost(true) . __PS_BASE_URI__;
        $newUrl  = str_replace('/shop', '', $ShopUrl);

        // General Settings Secret
        $locale['webhook_secret']['desc'] .= str_replace(
            ['[link]'],
            ["{$newUrl}sibs/webhook"],
            '<br/>' . $this->l('Provide this WebHook URL [link] to your SIBS point of contact.')
        );

        $locale['TITLE_GENERAL_SETTING'] = $this->l('GENERAL SETTING');

        //Oneclick
        $locale['oneclick']['label'] = $this->l('Tokenization');

        $locale['oneclick']['none']         = $this->l('Inexistente');
        $locale['oneclick']['tokenization'] = $this->l('Tokenization');
        $locale['oneclick']['oneclick']     = $this->l('OneClick');

        return $locale;
    }

    private function getPaymentForm($locale)
    {
        SibsLog::warning('DEBUG: getPaymentForm....');

        $paymentForm = [];
        foreach ($this->payment_methods as $key => $value) {
            $paymentName   = Tools::strtolower($value);
            $paymentForm[] = [
                'form' => [
                    'legend' => [
                        'title' => $locale["$paymentName"],
                    ],
                    'input' => [
                        $this->getSwitchForm(
                            "{$value}_ACTIVE",
                            $locale['active'],
                            $this->getSwitchList('active')
                        ),
                        $this->getTextForm(
                            "{$value}_SORT",
                            $locale['order']
                        ),
                    ],
                    'submit' => [
                        'title' => $locale['save'],
                    ],
                ],
            ];

            if (in_array($value, $this->db_pa_payment_methods)) {
                if ($value == SibsConstants::PAYMENT_METHOD_CREDIT_CARD) {
                    // card db or pa (drop down menu)
                    $addTransactionMode = $this->getSelectForm(
                        "{$value}_MODE",
                        $locale['mode'],
                        $this->getTransactionModeList(
                            $locale['mode']['db'],
                            $locale['mode']['pa']
                        )
                    );

                    array_push($paymentForm[$key]['form']['input'], $addTransactionMode);

                    // card oneclick date Type (drop down menu)
                    $paymentDate = $this->getSelectForm(
                        "{$value}_ONECLICK",
                        $locale['oneclick'],
                        $this->getOneclickList(
                            $locale['oneclick']['none'],
                            $locale['oneclick']['tokenization'],
                            $locale['oneclick']['oneclick']
                        )
                    );
                    array_push($paymentForm[$key]['form']['input'], $paymentDate);
                }
            }

            if (in_array($value, $this->card_payment_methods)) {
                $cardTypesList = $this->getCCTypesList($locale['cardtype']);

                $addCardType = $this->getMultiSelectForm("{$value}_CARDS", $locale['cardtype'], $cardTypesList);
                array_push($paymentForm[$key]['form']['input'], $addCardType);
            }

            if ($value == SibsConstants::PAYMENT_METHOD_PAY_BY_LINK) {
                // pay by link expiration value
                $expirationPaymentValue = $this->getTextForm("{$value}_EXPIRATION_PAYMENT_VALUE", $locale['payment_expiration_value']);
                array_push($paymentForm[$key]['form']['input'], $expirationPaymentValue);
                // pay by link date Type (drop down menu)
                $expirationPaymentDate = $this->getSelectForm(
                    "{$value}_EXPIRATION_PAYMENT_TYPE",
                    $locale['payment_expiration_type'],
                    $this->getPblList(
                        $locale['payment_expiration_type']['minute'],
                        $locale['payment_expiration_type']['hour'],
                        $locale['payment_expiration_type']['day'],
                        $locale['payment_expiration_type']['month']
                    )
                );
                array_push($paymentForm[$key]['form']['input'], $expirationPaymentDate);
            }

            if ($value == SibsConstants::PAYMENT_METHOD_BLIK) {
                $paymentRetriesValue = $this->getTextForm("{$value}_NUMBER_OF_RETRIES_VALUE", $locale['number_of_retries']);
                array_push($paymentForm[$key]['form']['input'], $paymentRetriesValue);

                $paymentDelayRetriesValue = $this->getTextForm("{$value}_DELAY_BETWEEN_RETRIES_VALUE", $locale['delay_between_retries']);
                array_push($paymentForm[$key]['form']['input'], $paymentDelayRetriesValue);
            }
        }

        return $paymentForm;
    }

    private function getGeneralForm($locale)
    {
        SibsLog::warning('DEBUG: getGeneralForm....');

        //get environment variables from configuration file
        $environment_file = $this->getEnvironmentConfig();

        foreach ($environment_file['environment'] as $value) {
            $environment[$value] = $value;
        }

        $generalForm = [];

        $generalForm[] = [
            'form' => [
                'legend' => [
                    'title' => $locale['TITLE_GENERAL_SETTING'],
                ],
                'input' => [
                    $this->getTextForm(
                        'GENERAL_TERMINALID',
                        $locale['terminalid'],
                        true
                    ),
                    $this->getTextAreaForm(
                        'GENERAL_BEARER',
                        $locale['bearer'],
                        true
                    ),
                    $this->getTextForm(
                        'GENERAL_CLIENTID',
                        $locale['clientid'],
                        true
                    ),
                    $this->getSelectForm(
                        'GENERAL_ENVIRONMENT',
                        $locale['sibs_environment'],
                        $this->getSibsEnvironmentConfigLists(
                            $environment
                        )
                    ),
                    $this->getTextForm(
                        'WEBHOOK_SECRET',
                        $locale['webhook_secret']
                    ),
                ],
                'submit' => [
                    'title' => $locale['save'],
                ],
            ],
        ];

        return $generalForm;
    }

    private function getTextAreaForm($paymentMethod, $locale, $requirement = false)
    {
        $textForm = [
            'type'     => 'textarea',
            'name'     => "SIBS_{$paymentMethod}",
            'label'    => $locale['label'],
            'required' => $requirement,
            'desc'     => isset($locale['desc']) ? $locale['desc'] : '',
        ];

        return $textForm;
    }

    private function getTextForm($paymentMethod, $locale, $requirement = false)
    {
        $textForm = [
            'type'     => 'text',
            'name'     => "SIBS_{$paymentMethod}",
            'label'    => $locale['label'],
            'required' => $requirement,
            'desc'     => isset($locale['desc']) ? $locale['desc'] : '',
        ];

        return $textForm;
    }

    private function getSelectForm($paymentMethod, $locale, $selectList)
    {
        $selectForm = [
            'type'    => 'select',
            'name'    => "SIBS_{$paymentMethod}",
            'label'   => $locale['label'],
            'options' => [
                'query' => $selectList,
                'id'    => 'id',
                'name'  => 'name',
            ],
            'desc' => ! empty($locale['desc']) ? $locale['desc'] : '',
        ];

        return $selectForm;
    }

    private function getMultiSelectForm($paymentMethod, $locale, $multiSelectList)
    {
        $selectForm = [
            'id'       => "SIBS_{$paymentMethod}",
            'type'     => 'select',
            'name'     => "SIBS_{$paymentMethod}[]",
            'label'    => $locale['label'],
            'multiple' => true,
            'options'  => [
                'query' => $multiSelectList,
                'id'    => 'id',
                'name'  => 'name',
            ],
            'desc' => ! empty($locale['desc']) ? $locale['desc'] : '',
        ];

        return $selectForm;
    }

    private function getSwitchForm($paymentMethod, $locale, $switchList)
    {
        $switchForm = [
            'type'    => 'switch',
            'label'   => $locale['label'],
            'name'    => "SIBS_{$paymentMethod}",
            'is_bool' => true,
            'values'  => $switchList,
            'desc'    => ! empty($locale['desc']) ? $locale['desc'] : '',
        ];

        return $switchForm;
    }

    /*
    *    Form Content (Enabled, Server, Transaction-mode, Cards Types)
    */

    //Enabled
    private function getSwitchList($field)
    {
        $list = [
            [
                'id'    => "{$field}_on",
                'value' => 1,
            ], [
                'id'    => "{$field}_off",
                'value' => 0,
            ],
        ];

        return $list;
    }

    // pay by link date options
    private function getPblList($chModeMinute, $chModeHour, $chModeDay, $chModeMonth)
    {
        $listChServer = [
            [
                'id'   => 'minute',
                'name' => $chModeMinute,
            ], [
                'id'   => 'hour',
                'name' => $chModeHour,
            ], [
                'id'   => 'day',
                'name' => $chModeDay,
            ], [
                'id'   => 'month',
                'name' => $chModeMonth,
            ],
        ];

        return $listChServer;
    }

    // oneclick date options
    private function getOneclickList($chModeNone, $chModeTokenization, $chModeOneclick)
    {
        $listChServer = [
            [
                'id'   => SibsConstants::SIBS_TOKEN_NONE,
                'name' => $chModeNone,
            ], [
                'id'   => SibsConstants::SIBS_TOKEN_TOKENIZATION,
                'name' => $chModeTokenization,
            ], [
                'id'   => SibsConstants::SIBS_TOKEN_ONECLICK,
                'name' => $chModeOneclick,
            ],
        ];

        return $listChServer;
    }

    /**
     * custom more list.
     *
     * @param array $options
     *
     * @return array $listSibsConfigs
     */
    private function getSibsEnvironmentConfigLists($options)
    {
        $listSibsConfigs = [];

        if (is_array($options)) {
            foreach ($options as $list) {
                $listSibsConfigs[] = [
                    'id'   => $list,
                    'name' => $list,
                ];
            }
        }

        return $listSibsConfigs;
    }

    //Transaction-mode
    private function getTransactionModeList($chModeDebit, $chModePreauth)
    {
        $listChMode = [
            [
                'id'   => SibsConstants::PAYMENT_MODE_DEBIT,
                'name' => $chModeDebit,
            ], [
                'id'   => SibsConstants::PAYMENT_MODE_AUTH,
                'name' => $chModePreauth,
            ],
        ];

        return $listChMode;
    }

    //Cards Types
    private function getCCTypesList($cardTypes)
    {
        $listChCardType = [
            [
                'id'   => SibsConstants::SIBS_CREDIT_CARD_AMEX,
                'name' => $cardTypes['amex'],
            ], [
                'id'   => SibsConstants::SIBS_CREDIT_CARD_MAESTRO,
                'name' => $cardTypes['maestro'],
            ], [
                'id'   => SibsConstants::SIBS_CREDIT_CARD_MASTER,
                'name' => $cardTypes['master'],
            ], [
                'id'   => SibsConstants::SIBS_CREDIT_CARD_MASTERDEBIT,
                'name' => $cardTypes['masterdebit'],
            ], [
                'id'   => SibsConstants::SIBS_CREDIT_CARD_VISA,
                'name' => $cardTypes['visa'],
            ], [
                'id'   => SibsConstants::SIBS_CREDIT_CARD_VISADEBIT,
                'name' => $cardTypes['visadebit'],
            ], [
                'id'   => SibsConstants::SIBS_CREDIT_CARD_VISAELECTRON,
                'name' => $cardTypes['visaelectron'],
            ], [
                'id'   => SibsConstants::SIBS_CREDIT_CARD_VPAY,
                'name' => $cardTypes['vpay'],
            ],
        ];

        return $listChCardType;
    }

    public function sibsOrderStatus($sibsOrder)
    {
        SibsLog::info('INIT ORDER_STATUS');

        try {
            $orderID       = $sibsOrder['id_order'];
            $transactionID = $sibsOrder['id_transaction'];

            SibsLog::info("orderId: $orderID");
            SibsLog::info("transactionID: $transactionID");

            $credentials = SibsUtils::getCredentials();
            $resultJson  = SibsPaymentCore::getPaymentStatus($transactionID, $credentials);

            SibsLog::info("resultJson: $resultJson");

            if (! $resultJson) {
                throw new SibsException('ERROR_GENERAL_NORESPONSE');
            }

            $response      = $resultJson['response'];
            $paymentMethod = $response['paymentMethod'];
            $paymentStatus = $response['paymentStatus'];
            $returnCode    = $response['returnStatus']['statusCode'];

            $captureAmountCurrency = $response['amount']['currency'];
            $captureAmount         = $response['amount']['value'];
            SibsLog::info('Status: ' . print_r($response, true));

            SibsLog::info("returnCode: $returnCode");
            SibsLog::info("paymentStatus: $paymentStatus");

            $transactionResult = SibsPaymentCore::getTransactionResult($returnCode, $paymentStatus);

            if ($transactionResult !== SibsConstants::SIBS_ACK) {
                throw new SibsException('Error on Order Status');
            }

            $orderInquiryStatus = SibsPaymentCore::sibs_convert_response_status_to_payment_status($paymentMethod, $paymentStatus);

            $order       = new \Order($orderID);
            $orderStatus = $order->getCurrentState();

            if ($response['paymentStatus'] == SibsConstants::PAYMENT_STATUS_SUCCESS) {
                $employeeID = (int) $this->context->employee->id;
                SibsPaymentCore::saveOrderHistory($orderID, SibsConstants::ORDER_STATUS_PAYMENT, $employeeID);
            }

            $resultJsonLog                       = [];
            $resultJsonLog['transactionID']      = $transactionID;
            $resultJsonLog['paymentType']        = $response['paymentType'];
            $resultJsonLog['paymentStatus']      = $response['paymentStatus'];
            $resultJsonLog['amount']['currency'] = $captureAmountCurrency;
            $resultJsonLog['amount']['value']    = $captureAmount;
            $payment_method                      = $order->payment_method;

            try {
                SibsModels::saveTransactionRefundLog($orderID, '(Order Status) ' . $response['paymentStatus'], $resultJsonLog);
            } catch (Exception $e) {
                SibsLog::info($e->getMessage());
            }

            $data = [
                'orderId' => $orderID,
            ];
            $message = $this->getSuccessTranslatedMessage('Status complete (ACK) for order #[orderId]', $data);

            $this->adminStatusConfirmationMessage('Status check complete', $message, $data);
        } catch(SibsException $e) {
            $error   = SibsPaymentCore::getErrorIdentifier();
            $message = $e->getErrorMessage();

            $this->adminStatusErrorMessage($error, $message, []);
        }

        $this->context->smarty->assign('refresh_page', true);
        SibsLog::info('END ORDER_STATUS');
    }

    public function sibsCapture($sibsOrder)
    {
        SibsLog::info('INIT CAPTURE');

        try {
            $orderID       = (int) $sibsOrder['id_order'];
            $transactionID = $sibsOrder['id_transaction'];
            $captureAmount = Tools::getValue('capture_amount');

            $transactionData = $this->getTransactionalCaptureData($sibsOrder, $captureAmount);

            $resultJson = SibsPaymentCore::backOfficeOperation($transactionID, $transactionData);

            if (! $resultJson) {
                throw new SibsException('ERROR_GENERAL_NORESPONSE');
            }

            $response = $resultJson['response'];

            $returnCode            = $response['returnStatus']['statusCode'];
            $captureStatus         = $response['paymentStatus'];
            $captureID             = $response['transactionID'];
            $captureAmountCurrency = $response['amount']['currency'];
            $data                  = [
                'orderID'  => $orderID,
                'amount'   => $captureAmount,
                'currency' => $captureAmountCurrency,
            ];

            SibsModels::updateOrderRefCaptureStatus(
                $orderID,
                SibsPaymentCore::sibs_convert_response_status_to_capture_payment_status($captureStatus)
            );
            $transactionResult = SibsPaymentCore::getTransactionResult($returnCode, $captureStatus);

            if ($transactionResult !== SibsConstants::SIBS_ACK) {
                throw new SibsException('Error on Capture');
            }

            SibsModels::updateOrderRefCaptureID($orderID, $captureID);

            $sibsOrder = new \Order($orderID);

            $resultJsonLog                       = [];
            $resultJsonLog['transactionID']      = $response['transactionID'];
            $resultJsonLog['paymentType']        = $transactionData['paymentType'];
            $resultJsonLog['paymentStatus']      = $response['paymentStatus'];
            $resultJsonLog['amount']['currency'] = $captureAmountCurrency;
            $resultJsonLog['amount']['value']    = $captureAmount;
            $payment_method                      = $sibsOrder->payment_method;

            try {
                SibsModels::saveTransactionRefundLog($orderID, SibsConstants::PAYMENT_TYPE_CAPT, $resultJsonLog);
            } catch (Exception $e) {
                SibsLog::info($e->getMessage());
            }

            $employeeID = (int) $this->context->employee->id;
            SibsPaymentCore::saveOrderHistory($orderID, SibsConstants::ORDER_STATUS_PAYMENT, $employeeID);

            $message = $this->getSuccessTranslatedMessage('Capture done for order #[orderId] with [amount] [currency]', $data);
            SibsModels::updateOrderRefCaptureMessage($orderID, $message);

            $this->adminStatusConfirmationMessage('Capture complete', $message, $data);
        } catch(SibsException $e) {
            $error   = SibsPaymentCore::getErrorIdentifier();
            $message = $e->getErrorMessage();

            $this->adminStatusErrorMessage($error, $message, []);
        }

        $this->context->smarty->assign('refresh_page', true);
        SibsLog::info('END CAPTURE');
    }

    public function sibsRefundParcial($sibsOrder, $PsOrder, $params)
    {
        // @todo: criação de uma versao para fazer devolucao parcial.
        SibsLog::info('INIT SIBS_REFUND_PARCIAL');

        try {
            $orderID       = (int) ($sibsOrder['id_order']);
            $paymentType   = $sibsOrder['payment_type'];
            $transactionID = ($paymentType === SibsConstants::PAYMENT_TYPE_AUTH) ? $sibsOrder['id_captured'] : $sibsOrder['id_transaction'];
            $refundAmount  = round($params['cancel_amount'], 2);

            $transactionData = $this->getTransactionalRefundData($sibsOrder, $refundAmount);
            $resultJson      = SibsPaymentCore::backOfficeOperation($transactionID, $transactionData);

            if (! $resultJson) {
                throw new SibsException('ERROR_GENERAL_NORESPONSE');
            }

            $response = $resultJson['response'];

            if (! isset($response['paymentStatus'])) {
                throw new SibsException('ERROR_GENERAL_NORESPONSE');
            }

            $returnCode           = $response['returnStatus']['statusCode'];
            $refundStatus         = $response['paymentStatus'];
            $refundID             = $response['transactionID'];
            $refundAmountCurrency = $response['amount']['currency'];

            $data = [
                'orderId'  => $orderID,
                'amount'   => $refundAmount,
                'currency' => $refundAmountCurrency,
            ];

            SibsModels::updateOrderRefRefundStatus($orderID, $refundStatus);

            $transactionResult = SibsPaymentCore::getTransactionResult(
                $returnCode,
                SibsPaymentCore::sibs_convert_response_status_to_capture_payment_status($refundStatus)
            );

            if ($transactionResult !== SibsConstants::SIBS_ACK) {
                throw new SibsException('Error on Refund');
            }

            $resultJsonLog                       = [];
            $resultJsonLog['transactionID']      = $response['transactionID'];
            $resultJsonLog['paymentType']        = $transactionData['paymentType'];
            $resultJsonLog['paymentStatus']      = $response['paymentStatus'];
            $resultJsonLog['amount']['currency'] = $refundAmountCurrency;
            $resultJsonLog['amount']['value']    = $refundAmount;

            SibsModels::updateOrderRefRefundID($orderID, $refundID);
            SibsModels::saveTransactionRefundLog($orderID, SibsConstants::PAYMENT_TYPE_RFND, $resultJsonLog);

            $orderRefundStatus = SibsPaymentCore::getOrderRefundStatus($refundStatus);

            $employeeID = (int) $this->context->employee->id;
            SibsPaymentCore::saveOrderHistory($orderID, $orderRefundStatus, $employeeID);

            if ($orderRefundStatus === SibsConstants::ORDER_STATUS_SIBS_REFUND_PENDING) {
                $message         = $this->getSuccessTranslatedMessage('Refund done for order #[orderId] with [amount] [currency]', $data);
                $completeMessage = 'Refund complete';
            } elseif ($orderRefundStatus === SibsConstants::ORDER_STATUS_REFUND) {
                $message         = $this->getSuccessTranslatedMessage('Refund pending for order #[orderId] with [amount] [currency]', $data);
                $completeMessage = 'Refund is pending';
            }

            SibsModels::updateOrderRefRefundMessage($orderID, $message);

            $this->adminStatusConfirmationMessage($completeMessage, $message, $data);
        } catch(SibsException $e) {
            SibsLog::info('SibsException SIBS_REFUND_PARCIAL');
            SibsLog::info($e->getErrorMessage());
            $error   = SibsPaymentCore::getErrorIdentifier();
            $message = $e->getErrorMessage();

            $this->adminStatusErrorMessage($error, $message, []);
        }

        $this->context->smarty->assign('refresh_page', true);
        SibsLog::info('END SIBS_REFUND_PARCIAL');
    }

    public function sibsRefund($sibsOrder)
    {
        SibsLog::info('INIT SIBS_REFUND');

        try {
            $orderID       = (int) ($sibsOrder['id_order']);
            $paymentType   = $sibsOrder['payment_type'];
            $transactionID = ($paymentType === SibsConstants::PAYMENT_TYPE_AUTH) ? $sibsOrder['id_captured'] : $sibsOrder['id_transaction'];
            $refundAmount  = Tools::getValue('refund_amount');

            $transactionData = $this->getTransactionalRefundData($sibsOrder, $refundAmount);

            $resultJson = SibsPaymentCore::backOfficeOperation($transactionID, $transactionData);

            if (! $resultJson) {
                throw new SibsException('ERROR_GENERAL_NORESPONSE');
            }

            $response             = $resultJson['response'];
            $returnCode           = $response['returnStatus']['statusCode'];
            $refundStatus         = $response['paymentStatus'];
            $refundID             = $response['transactionID'];
            $refundAmountCurrency = $response['amount']['currency'];

            $data = [
                'orderId'  => $orderID,
                'amount'   => $refundAmount,
                'currency' => $refundAmountCurrency,
            ];

            SibsModels::updateOrderRefRefundStatus($orderID, $refundStatus);
            $transactionResult = SibsPaymentCore::getTransactionResult(
                $returnCode,
                SibsPaymentCore::sibs_convert_response_status_to_capture_payment_status($refundStatus)
            );

            if ($transactionResult !== SibsConstants::SIBS_ACK) {
                throw new SibsException('Error on Refund');
            }

            $resultJsonLog                       = [];
            $resultJsonLog['transactionID']      = $response['transactionID'];
            $resultJsonLog['paymentType']        = $transactionData['paymentType'];
            $resultJsonLog['paymentStatus']      = $response['paymentStatus'];
            $resultJsonLog['amount']['currency'] = $refundAmountCurrency;
            $resultJsonLog['amount']['value']    = $refundAmount;

            SibsModels::updateOrderRefRefundID($orderID, $refundID);
            SibsModels::saveTransactionRefundLog($orderID, SibsConstants::PAYMENT_TYPE_RFND, $resultJsonLog);

            $orderRefundStatus = SibsPaymentCore::getOrderRefundStatus($refundStatus);

            $employeeID = (int) $this->context->employee->id;
            SibsPaymentCore::saveOrderHistory($orderID, $orderRefundStatus, $employeeID);

            if ($orderRefundStatus === SibsConstants::ORDER_STATUS_SIBS_REFUND_PENDING) {
                $message         = $this->getSuccessTranslatedMessage('Refund done for order #[orderId] with [amount] [currency]', $data);
                $completeMessage = 'Refund complete';
            } elseif ($orderRefundStatus === SibsConstants::ORDER_STATUS_REFUND) {
                $message         = $this->getSuccessTranslatedMessage('Refund pending for order #[orderId] with [amount] [currency]', $data);
                $completeMessage = 'Refund is pending';
            }

            SibsModels::updateOrderRefRefundMessage($orderID, $message);

            $this->adminStatusConfirmationMessage($completeMessage, $message, $data);
        } catch(SibsException $e) {
            $error   = SibsPaymentCore::getErrorIdentifier();
            $message = $e->getErrorMessage();

            $this->adminStatusErrorMessage($error, $message, []);
        }

        $this->context->smarty->assign('refresh_page', true);
        SibsLog::info('END SIBS_REFUND');
    }

    public function getSuccessTranslatedMessage($message, $data)
    {
        foreach ($data as $key => $value) {
            $message = str_replace("[$key]", $value, $this->l($message));
        }

        return $message;
    }

    public function sibsMakeContext($sibsOrder)
    {
        SibsLog::info('INIT SIBS_MAKE_CONTEXT');

        $key_show_order_status = null;
        $key_show_sibs_capture = null;
        $key_show_sibs_refund  = null;
        $key_show_refund       = null;

        $orderID  = (int) ($sibsOrder['id_order']);
        $order    = new \Order($orderID);
        $currency = new \Currency((int) $order->id_currency);

        $current_state = $order->getCurrentState();

        $payment_method = $sibsOrder['payment_method'];
        $refund_status  = $sibsOrder['refund_status'];

        SibsLog::info("payment_method: $payment_method");
        SibsLog::info("refund_status: $refund_status");

        switch ($current_state) {
            case Configuration::get(SibsConstants::ORDER_STATUS_SIBS_PENDING):
                $key_show_order_status = '1';

                break;
            case Configuration::get(SibsConstants::ORDER_STATUS_SIBS_AUTHORIZED):
                $key_show_sibs_capture = '1';

                break;
            case Configuration::get(SibsConstants::ORDER_STATUS_PAYMENT):
                $key_show_refund = '1';

                break;
        }

        if ($refund_status == SibsConstants::CAPTURE_REFUND_STATUS_PENDING) {
            $key_show_sibs_refund = '1';
        }

        SibsLog::info("key_show_refund: $key_show_refund");
        SibsLog::info("key_show_sibs_capture: $key_show_sibs_capture");
        SibsLog::info("key_show_order_status: $key_show_order_status");
        SibsLog::info("key_show_sibs_refund: $key_show_sibs_refund");

        $this->context->smarty->assign('id_transaction', $sibsOrder['id_transaction']);
        $this->context->smarty->assign('payment_method', $sibsOrder['payment_method']);
        $this->context->smarty->assign('amount', $sibsOrder['amount']);
        $this->context->smarty->assign('currency', $sibsOrder['currency']);

        $this->context->smarty->assign('currency_sign', $currency->sign);

        $this->context->smarty->assign('key_status', $key_show_order_status);
        $this->context->smarty->assign('key_sibs_capture', $key_show_sibs_capture);
        $this->context->smarty->assign('key_sibs_refund', $key_show_sibs_refund);
        $this->context->smarty->assign('key_refund', $key_show_refund);

        SibsLog::info('END SIBS_MAKE_CONTEXT');
    }

    private function getTransactionalRefundData($sibsOrder, $amount)
    {
        return $this->getTransactionalData($sibsOrder, $amount, SibsConstants::PAYMENT_MODE_RFND);
    }

    private function getTransactionalCaptureData($sibsOrder, $amount)
    {
        return $this->getTransactionalData($sibsOrder, $amount, SibsConstants::PAYMENT_MODE_CAPT);
    }

    private function getTransactionalData($sibsOrder, $amount, $paymentType)
    {
        $credentials   = SibsUtils::getCredentials();
        $config_values = Sibs::getVersionData();

        $transactionData = [
            'test_mode'   => SibsUtils::getTestMode($sibsOrder['payment_method']),
            'paymentType' => $paymentType,
            'amount'      => $amount,
            'currency'    => $sibsOrder['currency'],
            'token'       => $credentials['token'],
            'server_mode' => $credentials['server_mode'],
            'merchant'    => [
                'terminalId'            => $config_values['terminalid'],
                'channel'               => $credentials['channel_id'],
                'merchantTransactionId' => $sibsOrder['id_transaction'],
            ],
            'transaction' => [
                'transactionTimestamp' => date('Y-m-d\TH:i:s.BP'),
                'description'          => "Transaction for order number {$sibsOrder['id_order']} terminalId {$config_values['terminalid']}",
                'amount'               => [
                    'value'    => $amount,
                    'currency' => $sibsOrder['currency'],
                ],
            ],
            'originalTransaction' => [
                'id'       => $sibsOrder['id_transaction'],
                'datetime' => $sibsOrder['payment_date'],
            ],
        ];

        return $transactionData;
    }

    public static function translate_message($message, $data = [])
    {
        foreach ($data as $key => $value) {
            $message = str_replace("[$key]", $value, $message);
        }

        return $message;
    }

    private function adminStatusConfirmationMessage($confirmation, $message, $data = [])
    {
        $this->context->controller->confirmations[] = $this->l($confirmation);
        $this->adminStatusMessage($message, $data);
    }

    private function adminStatusErrorMessage($error, $message, $data = [])
    {
        $this->context->controller->errors[] = $this->l($error);
        $this->adminStatusMessage($message, $data);
    }

    private function adminStatusMessage($message, $data = [])
    {
        $translated_message = $this->l($message);
        foreach ($data as $key => $value) {
            $translated_message = str_replace("[$key]", $value, $translated_message);
        }
        // TODO: Other way to have the status message
        $this->context->smarty->assign('status_message', $translated_message);
    }

    private function getConfigGeneralValues()
    {
        $saveConfig                          = [];
        $saveConfig['SIBS_GENERAL_CLIENTID'] = Tools::getValue(
            'SIBS_GENERAL_CLIENTID',
            Configuration::get('SIBS_GENERAL_CLIENTID')
        );

        $saveConfig['SIBS_GENERAL_TERMINALID'] = Tools::getValue(
            'SIBS_GENERAL_TERMINALID',
            Configuration::get('SIBS_GENERAL_TERMINALID')
        );

        $saveConfig['SIBS_GENERAL_BEARER'] = Tools::getValue(
            'SIBS_GENERAL_BEARER',
            Configuration::get('SIBS_GENERAL_BEARER')
        );

        $saveConfig['SIBS_WEBHOOK_SECRET'] = Tools::getValue(
            'SIBS_WEBHOOK_SECRET',
            Configuration::get('SIBS_WEBHOOK_SECRET')
        );

        $saveConfig['SIBS_GENERAL_ENVIRONMENT'] = Tools::getValue(
            'SIBS_GENERAL_ENVIRONMENT',
            Configuration::get('SIBS_GENERAL_ENVIRONMENT')
        );

        return $saveConfig;
    }

    public function getConfigFieldsValues()
    {
        $saveConfig = $this->getConfigGeneralValues();

        foreach ($this->payment_methods as $value) {
            $saveConfig["SIBS_{$value}_ACTIVE"] = Tools::getValue(
                "SIBS_{$value}_ACTIVE",
                Configuration::get("SIBS_{$value}_ACTIVE")
            );

            // debit/authorization methods
            if (in_array($value, $this->db_pa_payment_methods)) {
                $saveConfig["SIBS_{$value}_MODE"] = Tools::getValue(
                    "SIBS_{$value}_MODE",
                    Configuration::get("SIBS_{$value}_MODE")
                );
            }

            $saveConfig["SIBS_{$value}_SORT"] = Tools::getValue(
                "SIBS_{$value}_SORT",
                Configuration::get("SIBS_{$value}_SORT")
            );

            // card payment methods
            if (in_array($value, $this->card_payment_methods)) {
                $saveConfig["SIBS_{$value}_CARDS[]"] = Tools::getValue(
                    "SIBS_{$value}_CARDS",
                    Configuration::get("SIBS_{$value}_CARDS")
                );

                $saveConfig["SIBS_{$value}_ONECLICK"] = Tools::getValue(
                    "SIBS_{$value}_ONECLICK",
                    Configuration::get("SIBS_{$value}_ONECLICK")
                );
            }

            // pay by link method
            if ($value == SibsConstants::PAYMENT_METHOD_PAY_BY_LINK) {
                // payment value
                $saveConfig["SIBS_{$value}_EXPIRATION_PAYMENT_VALUE"] = Tools::getValue(
                    "SIBS_{$value}_EXPIRATION_PAYMENT_VALUE",
                    Configuration::get("SIBS_{$value}_EXPIRATION_PAYMENT_VALUE")
                );

                // payment type
                $saveConfig["SIBS_{$value}_EXPIRATION_PAYMENT_TYPE"] = Tools::getValue(
                    "SIBS_{$value}_EXPIRATION_PAYMENT_TYPE",
                    Configuration::get("SIBS_{$value}_EXPIRATION_PAYMENT_TYPE")
                );

                // payment link value
                $saveConfig["SIBS_{$value}_EXPIRATION_PAYMENT_LINK_VALUE"] = Tools::getValue(
                    "SIBS_{$value}_EXPIRATION_PAYMENT_LINK_VALUE",
                    Configuration::get("SIBS_{$value}_EXPIRATION_PAYMENT_LINK_VALUE")
                );

                // payment link type
                $saveConfig["SIBS_{$value}_EXPIRATION_PAYMENT_LINK_TYPE"] = Tools::getValue(
                    "SIBS_{$value}_EXPIRATION_PAYMENT_LINK_TYPE",
                    Configuration::get("SIBS_{$value}_EXPIRATION_PAYMENT_LINK_TYPE")
                );
            }

            // blik method
            if ($value == SibsConstants::PAYMENT_METHOD_BLIK) {
                $saveConfig["SIBS_{$value}_NUMBER_OF_RETRIES_VALUE"] = Tools::getValue(
                    "SIBS_{$value}_NUMBER_OF_RETRIES_VALUE",
                    Configuration::get("SIBS_{$value}_NUMBER_OF_RETRIES_VALUE")
                );

                $saveConfig["SIBS_{$value}_DELAY_BETWEEN_RETRIES_VALUE"] = Tools::getValue(
                    "SIBS_{$value}_DELAY_BETWEEN_RETRIES_VALUE",
                    Configuration::get("SIBS_{$value}_DELAY_BETWEEN_RETRIES_VALUE")
                );
            }

            if (! Tools::isSubmit('btnSubmit')) {
                $saveConfig["SIBS_{$value}_CARDS[]"] = isset($saveConfig["SIBS_{$value}_CARDS[]"]) ?
                    explode(',', $saveConfig["SIBS_{$value}_CARDS[]"]) :
                    [];
            }
        }

        return $saveConfig;
    }

    public function getPaymentDescription($paymentMethod)
    {
        $transactionMode = Configuration::get("SIBS_{$paymentMethod}_MODE");

        switch ($paymentMethod) {
            case SibsConstants::PAYMENT_METHOD_CREDIT_CARD:
                if ($transactionMode == SibsConstants::PAYMENT_MODE_DEBIT) {
                    $paymentDescription = $this->getTranslation('SIBS_TT_CC_DEBIT', SibsConstants::SIBS_FRONTEND_CREDIT_CARD_DEBIT);
                } elseif ($transactionMode == SibsConstants::PAYMENT_MODE_AUTH) {
                    $paymentDescription = $this->getTranslation('SIBS_TT_CC_PREAUTH', SibsConstants::SIBS_FRONTEND_CREDIT_CARD);
                } else {
                    $paymentDescription = '';
                }

                break;
            case SibsConstants::PAYMENT_METHOD_BLIK:
                $paymentDescription = $this->getTranslation('SIBS_TT_BLIK', SibsConstants::SIBS_FRONTEND_BLIK);

                break;
            case SibsConstants::PAYMENT_METHOD_PAY_BY_LINK:
                $paymentDescription = $this->getTranslation('SIBS_TT_PBL', SibsConstants::SIBS_FRONTEND_PAY_BY_LINK);

                break;
            default:
                $paymentDescription = '';

                break;
        }

        return $paymentDescription;
    }

    public function getTranslation($translationKey, $default = 'Undefined')
    {
        return ($translationKey !== $this->l($translationKey)) ? $this->l($translationKey) : $default;
    }

    public function getSuccessMessage($successIdentifier)
    {
        $returnMessage = '';

        switch ($successIdentifier) {
            case 'SUCCESS_MC_ADD':
                $returnMessage = $this->getTranslation('SUCCESS_MC_ADD', 'Congratulations, your payment information were successfully saved.');

                break;
            case 'SUCCESS_MC_UPDATE':
                $returnMessage = $this->getTranslation('SUCCESS_MC_UPDATE', 'Congratulations, your payment information were successfully updated.');

                break;
            case 'SUCCESS_MC_DELETE':
                $returnMessage = $this->getTranslation('SUCCESS_MC_DELETE', 'Congratulations, your payment information were successfully deleted.');

                break;
            default:
                $returnMessage = '';

                break;
        }

        return $returnMessage;
    }

    public function getErrorMessage($errorIdentifier)
    {
        $returnMessage = '';

        switch ($errorIdentifier) {
            case 'ERROR_PARAMETER_CART':
                $returnMessage = $this->getTranslation('ERROR_PARAMETER_CART', 'Please fill your shopping cart to make payment with Klarna.');

                break;
            case 'ERROR_ORDER_INVALID':
                $returnMessage = $this->getTranslation('ERROR_ORDER_INVALID', 'Your cart or your information is not complete. Please complete the information before make a payment.');

                break;
            case 'ERROR_MESSAGE_PCLASS_REQUIRED':
                $returnMessage = $this->getTranslation('ERROR_MESSAGE_PCLASS_REQUIRED', 'Transaction cannot be processed because PCLASS parameter is missing, please contact the shop admin for futher information.');

                break;
            case 'ERROR_GENERAL_NORESPONSE':
                $returnMessage = $this->getTranslation('ERROR_GENERAL_NORESPONSE', 'Unfortunately, the confirmation of your payment failed. Please contact your merchant for clarification.');

                break;
            case 'ERROR_GENERAL_FRAUD_DETECTION':
                $returnMessage = $this->getTranslation('ERROR_GENERAL_FRAUD_DETECTION', 'Unfortunately, there was an error while processing your order. In case a payment has been made, it will be automatically refunded.');

                break;
            case 'ERROR_CC_ACCOUNT':
                $returnMessage = $this->getTranslation('ERROR_CC_ACCOUNT', 'The account holder entered does not match your name. Please use an account that is registered on your name.');

                break;
            case 'ERROR_CC_INVALIDDATA':
                $returnMessage = $this->getTranslation('ERROR_CC_INVALIDDATA', 'Unfortunately, the card/account data you entered was not correct. Please try again.');

                break;
            case 'ERROR_CC_BLACKLIST':
                $returnMessage = $this->getTranslation('ERROR_CC_BLACKLIST', 'Unfortunately, the credit card you entered can not be accepted. Please choose a different card or payment method.');

                break;
            case 'ERROR_CC_DECLINED_CARD':
                $returnMessage = $this->getTranslation('ERROR_CC_DECLINED_CARD', 'Unfortunately, the credit card you entered can not be accepted. Please choose a different card or payment method.');

                break;
            case 'ERROR_CC_EXPIRED':
                $returnMessage = $this->getTranslation('ERROR_CC_EXPIRED', 'Unfortunately, the credit card you entered is expired. Please choose a different card or payment method.');

                break;
            case 'ERROR_CC_INVALIDCVV':
                $returnMessage = $this->getTranslation('ERROR_CC_INVALIDCVV', 'Unfortunately, the CVV/CVC you entered is not correct. Please try again.');

                break;
            case 'ERROR_CC_EXPIRY':
                $returnMessage = $this->getTranslation('ERROR_CC_EXPIRY', 'Unfortunately, the expiration date you entered is not correct. Please try again.');

                break;
            case 'ERROR_CC_LIMIT_EXCEED':
                $returnMessage = $this->getTranslation('ERROR_CC_LIMIT_EXCEED', 'Unfortunately, the limit of your credit card is exceeded. Please choose a different card or payment method.');

                break;
            case 'ERROR_CC_3DAUTH':
                $returnMessage = $this->getTranslation('ERROR_CC_3DAUTH', 'Unfortunately, the password you entered was not correct. Please try again.');

                break;
            case 'ERROR_CC_3DERROR':
                $returnMessage = $this->getTranslation('ERROR_CC_3DERROR', 'Unfortunately, there has been an error while processing your request. Please try again.');

                break;
            case 'ERROR_CC_NOBRAND':
                $returnMessage = $this->getTranslation('ERROR_CC_NOBRAND', 'Unfortunately, there has been an error while processing your request. Please try again.');

                break;
            case 'ERROR_GENERAL_LIMIT_AMOUNT':
                $returnMessage = $this->getTranslation('ERROR_GENERAL_LIMIT_AMOUNT', 'Unfortunately, your credit limit is exceeded. Please choose a different card or payment method.');

                break;
            case 'ERROR_GENERAL_LIMIT_TRANSACTIONS':
                $returnMessage = $this->getTranslation('ERROR_GENERAL_LIMIT_TRANSACTIONS', 'Unfortunately, your limit of transaction is exceeded. Please try again later.');

                break;
            case 'ERROR_CC_DECLINED_AUTH':
                $returnMessage = $this->getTranslation('ERROR_CC_DECLINED_AUTH', 'Unfortunately, your transaction has failed. Please choose a different card or payment method.');

                break;
            case 'ERROR_GENERAL_DECLINED_RISK':
                $returnMessage = $this->getTranslation('ERROR_GENERAL_DECLINED_RISK', 'Unfortunately, your transaction has failed. Please choose a different card or payment method.');

                break;
            case 'ERROR_CC_ADDRESS':
                $returnMessage = $this->getTranslation('ERROR_CC_ADDRESS', 'We are sorry. We could no accept your card as its origin does not match your address.');

                break;
            case 'ERROR_GENERAL_CANCEL':
                $returnMessage = $this->getTranslation('ERROR_GENERAL_CANCEL', 'You cancelled the payment prior to its execution. Please try again.');

                break;
            case 'ERROR_CC_RECURRING':
                $returnMessage = $this->getTranslation('ERROR_CC_RECURRING', 'Recurring transactions have been deactivated for this credit card. Please choose a different card or payment method.');

                break;
            case 'ERROR_CC_REPEATED':
                $returnMessage = $this->getTranslation('ERROR_CC_REPEATED', 'Unfortunately, your transaction has been declined due to invalid data. Please choose a different card or payment method.');

                break;
            case 'ERROR_GENERAL_ADDRESS':
                $returnMessage = $this->getTranslation('ERROR_GENERAL_ADDRESS', 'Unfortunately, your transaction has failed. Please check the personal data you entered.');

                break;
            case 'ERROR_GENERAL_BLACKLIST':
                $returnMessage = $this->getTranslation('ERROR_GENERAL_BLACKLIST', 'The chosen payment method is not available at the moment. Please choose a different card or payment method.');

                break;
            case 'ERROR_GENERAL_GENERAL':
                $returnMessage = $this->getTranslation('ERROR_GENERAL_GENERAL', 'Unfortunately, your transaction has failed. Please try again.');

                break;
            case 'ERROR_GENERAL_REDIRECT':
                $returnMessage = $this->getTranslation('ERROR_GENERAL_REDIRECT', 'Error before redirect.');

                break;
            case 'ERROR_GENERAL_TIMEOUT':
                $returnMessage = $this->getTranslation('ERROR_GENERAL_TIMEOUT', 'Unfortunately, your transaction has failed. Please try again.');

                break;
            case 'ERROR_GIRO_NOSUPPORT':
                $returnMessage = $this->getTranslation('ERROR_GIRO_NOSUPPORT', 'Giropay is not supported for this transaction. Please choose a different payment method.');

                break;
            case 'ERROR_ADDRESS_PHONE':
                $returnMessage = $this->getTranslation('ERROR_ADDRESS_PHONE', 'Unfortunately, your transaction has failed. Please enter a valid telephone number.');

                break;
            case 'ERROR_UNKNOWN':
                $returnMessage = $this->getTranslation('ERROR_UNKNOWN', 'Unfortunately, your transaction has failed. Please try again.');

                break;
            case 'ERROR_MC_UPDATE':
                $returnMessage = $this->getTranslation('ERROR_MC_UPDATE', 'We are sorry. Your attempt to update your payment information was not successful.');

                break;
            case 'ERROR_MC_ADD':
                $returnMessage = $this->getTranslation('ERROR_MC_ADD', 'We are sorry. Your attempt to save your payment information was not successful.');

                break;
            case 'ERROR_MC_DELETE':
                $returnMessage = $this->getTranslation('ERROR_MC_DELETE', 'We are sorry. Your attempt to delete your payment information was not successful.');

                break;
            case 'ERROR_CHARS':
                $returnMessage = $this->getTranslation('ERROR_CHARS', 'We are sorry. Error on chars.');

                break;
            default:
                $returnMessage = $this->getTranslation('ERROR_UNKNOWN', 'Unfortunately, your transaction has failed. Please try again.');

                break;
        }

        return $returnMessage;
    }

    public static function getEnvironmentConfig()
    {
        try {
            $json_file        = file_get_contents(_PS_MODULE_DIR_ . 'sibs/environment.json');
            $environment_file = json_decode($json_file, true);

            return $environment_file;
        } catch (Exception $e) {
            SibsLog::error('Error on accessing environment json: ' . $e->getMessage());

            return [];
        }
    }
}
