<?php
/**
 * 2007-2021 PrestaShop
 *
 * 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:
 * http://opensource.org/licenses/afl-3.0.php
 * 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-2021 PrestaShop SA
 * @license   http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
 *  International Registered Trademark & Property of PrestaShop SA
 */

// @codingStandardsIgnoreStart
/** @noinspection PhpMultipleClassDeclarationsInspection */
/** @noinspection PhpDeprecationInspection */
// @codingStandardsIgnoreEnd

namespace Prestashop\Module\AddonPayments\Form;

use addonpayments;
use AdminController;
use ComerciaGlobalPayments\AddonPayments\SDK\Api\EPGJs;
use Configuration;
use HelperForm;
use ImageManager;
use Language;
use Prestashop\Module\AddonPayments\AddonPaymentsConfig;
use Prestashop\Module\AddonPayments\Helpers\SecurityTrait;
use Tools;

/**
 * Implements module configuration form.
 */
class ConfigurationForm extends HelperForm
{
    use SecurityTrait;

    /**
     * @var \addonpayments
     */
    public $module;

    /**
     * @var \Prestashop\Module\AddonPayments\AddonPaymentsConfig
     */
    private $addonPaymentsConfig;

    public function __construct(addonpayments $module)
    {
        parent::__construct();

        $this->module = $module;
        $this->addonPaymentsConfig = new AddonPaymentsConfig($this->module);

        $this->show_toolbar = true;
        $this->identifier = 'id_module';
        $this->table = 'module';
        $this->default_form_language = $this->context->language->id;
        $this->allow_employee_form_lang = Configuration::get(
            'PS_BO_ALLOW_EMPLOYEE_FORM_LANG',
            0
        );

        $this->submit_action = $this->getSubmitName();
        $this->currentIndex = sprintf(
            '%s&configure=%s&tab_module=%s&module_name=%s',
            $this->context->link->getAdminLink(
                'AdminModules',
                false
            ),
            $this->module->name,
            $this->module->tab,
            $this->module->name
        );
        $this->token = Tools::getAdminTokenLite('AdminModules');

        $this->tpl_vars = [
            'fields_value' => $this->getValues(),
            'languages' => $this->context->controller->getLanguages(),
            'id_language' => $this->context->language->id,
        ];
        $this->toolbar_btn = [
            'save' => [
                    'desc' => $this->module->l('Save', 'configurationform'),
                    'href' => sprintf(
                        '%s&configure=%s&save%s&token=%s',
                        AdminController::$currentIndex,
                        $this->module->name,
                        $this->module->name,
                        Tools::getAdminTokenLite('AdminModules')
                    ),
                ],
            'back' => [
                'href' => sprintf(
                    '%s&token=%s',
                    AdminController::$currentIndex,
                    Tools::getAdminTokenLite('AdminModules')
                ),
                'desc' => $this->module->l('Back to list', 'configurationform'),
            ],
        ];


    }

    private function getSubmitName(): string
    {
        return "submit__{$this->module->name}__config";
    }

    private function getValues(): array
    {
        $encryptionKey = self::getEncryptionKey();
        $keys = [
          AddonPaymentsConfig::LIVE_MODE,
          AddonPaymentsConfig::DEFAULT_CONFIGURATION,
          AddonPaymentsConfig::TITLE,
          AddonPaymentsConfig::LOGO,
          AddonPaymentsConfig::MERCHANT_ID,
          AddonPaymentsConfig::MERCHANT_KEY,
          AddonPaymentsConfig::MERCHANT_PASSWORD,
          AddonPaymentsConfig::EPG_PRODUCT_ID,
          AddonPaymentsConfig::SETTLE,
          AddonPaymentsConfig::SUCCESS_URL,
          AddonPaymentsConfig::FAILURE_URL,
          AddonPaymentsConfig::CANCEL_URL,
          AddonPaymentsConfig::EPG_STYLE,
          AddonPaymentsConfig::PRINTED_KEY,
          AddonPaymentsConfig::BANNER_POSITION,
          AddonPaymentsConfig::BANNER_STYLE_COLOR,
          AddonPaymentsConfig::BANNER_STYLE_VARIANT,
          AddonPaymentsConfig::BANNER_STYLE_BRANDING,
        ];
        $encrypted = [
          AddonPaymentsConfig::MERCHANT_ID,
          AddonPaymentsConfig::MERCHANT_KEY,
          AddonPaymentsConfig::MERCHANT_PASSWORD,
        ];
        $translated = [
            AddonPaymentsConfig::TITLE,
            AddonPaymentsConfig::SUCCESS_URL,
            AddonPaymentsConfig::FAILURE_URL,
            AddonPaymentsConfig::CANCEL_URL,
        ];
        $languages = Language::getLanguages(true, false, true);
        $values = [];

        foreach ($keys as $key) {
            // Translations need to be handled later.
            if (in_array($key, $translated, true)) {
                foreach ($languages as $idLanguage) {
                    $values[$key][$idLanguage] = Configuration::get($key, $idLanguage);
                }
                continue;
            }

            $value = Configuration::get($key);

            if (in_array($key, $encrypted, true)) {
                $value = $this->decrypt($value, $encryptionKey);
            }

            $values[$key] = $value;
        }

        //Default values
        $values[AddonPaymentsConfig::DEFAULT_TITLE] = '';
        if(!empty($values[AddonPaymentsConfig::DEFAULT_CONFIGURATION])
           && AddonPaymentsConfig::DEFAULT_OPTION_CUSTOM !== $values[AddonPaymentsConfig::DEFAULT_CONFIGURATION] ) {
            $values[AddonPaymentsConfig::DEFAULT_TITLE] = $this->addonPaymentsConfig->getDefaultTitle($values[AddonPaymentsConfig::DEFAULT_CONFIGURATION]);
        }

        return $values;
    }

    public function render(): string
    {
        return $this->generateForm([$this->build()]);
    }

    private function build(): array
    {
        $default_configuration = Configuration::get(AddonPaymentsConfig::DEFAULT_CONFIGURATION);
        $logo = Configuration::get(AddonPaymentsConfig::LOGO);
        $empty = $this->addonPaymentsConfig->getDefaultLogoUri().'empty.png';

        if( !empty($default_configuration) && AddonPaymentsConfig::DEFAULT_OPTION_CUSTOM !== $default_configuration) {
            $image_default_uri = $this->addonPaymentsConfig->getDefaultLogoUri(). $default_configuration.'.png';
        }elseif(!empty($logo)){
            $image_path = $this->module->getLocalPath().'img'.DIRECTORY_SEPARATOR.$logo;
            $ext = substr($logo, strrpos($logo, '.') + 1);

            $image = ImageManager::thumbnail($image_path, $this->module->name."_logo".'.'.$ext, 100,
                $ext, true, true);

            $delete_url = $this->module->getAdminLink(
                'AdminModules',
                [
                    'configure' => 'addonpayments',
                    'tab_module' => 'payments_gateways',
                    'module_name'=> 'addonpayments',
                    'delete_image' => 1
                ]
            );
        }

        $hook = addonpayments::is17() ? 'hookDisplayReassurance' : 'hookDisplayProductButtons';
        $default_configuration = Configuration::get(AddonPaymentsConfig::DEFAULT_CONFIGURATION);
        $default_hidden = (!empty($default_configuration) && AddonPaymentsConfig::DEFAULT_OPTION_CUSTOM !== $default_configuration) ? '' : ' hidden';
        $custom_hidden = (!empty($default_configuration) && AddonPaymentsConfig::DEFAULT_OPTION_CUSTOM === $default_configuration) ? '' : ' hidden';

        return [
            'form' => [
                'input' => [
                    [
                        'type' => 'switch',
                        'label' => $this->module->l('Live mode', 'configurationform'),
                        'name' => AddonPaymentsConfig::LIVE_MODE,
                        'is_bool' => true,
                        'desc' => $this->module->l('Use this module in live mode', 'configurationform'),
                        'values' => [
                            [
                                'id' => 'active_on',
                                'value' => true,
                                'label' => $this->module->l('Enabled', 'configurationform'),
                            ],
                            [
                                'id' => 'active_off',
                                'value' => false,
                                'label' => $this->module->l('Disabled', 'configurationform'),
                            ],
                        ],
                    ],
                    [
                        'type' => 'select',
                        'label' => $this->module->l('Default configuration','configurationform'),
                        'name' => AddonPaymentsConfig::DEFAULT_CONFIGURATION,
                        'desc' => $this->module->l('Modify the title and logo configuration of the gateway or customise it if you prefer.', 'configurationform'),
                        'class' => 'ap-full-width ap-col-lg-3',
                        'options' => [
                            'query' => [
                                [
                                    'id_option' => '',
                                    'name' => $this->module->l('Select the default configuration', 'configurationform') ,
                                ],
                                [
                                    'id_option' => AddonPaymentsConfig::DEFAULT_OPTION_CREDIT_CARD,
                                    'name' => $this->module->l('Credit Card', 'configurationform') ,
                                ],
                                [
                                    'id_option' => AddonPaymentsConfig::DEFAULT_OPTION_CREDIT_CARD_BIZUM,
                                    'name' => $this->module->l('Credit Card and Bizum','configurationform'),
                                ],
                                [
                                    'id_option' => AddonPaymentsConfig::DEFAULT_OPTION_QUIX,
                                    'name' => $this->module->l('Quix financing','configurationform'),
                                ],
                                [
                                    'id_option' => AddonPaymentsConfig::DEFAULT_OPTION_MULTIPLE,
                                    'name' => $this->module->l('Multiple payment methods', 'configurationform'),
                                ],
                                [
                                   'id_option' => AddonPaymentsConfig::DEFAULT_OPTION_GLOBALPAYMENTS,
                                    'name' => $this->module->l('Powered by Globalpayments', 'configurationform'),
                                ],
                                [
                                    'id_option' => AddonPaymentsConfig::DEFAULT_OPTION_CUSTOM,
                                    'name' => $this->module->l('Custom', 'configurationform'),
                                ],

                            ],
                            'id' => 'id_option',
                            'name' => 'name'
                        ],
                    ],
                    [
                        'col' => 6,
                        'type' => 'text',
                        'required' => false,
                        'desc' => $this->module->l('This controls the title which the user sees during checkout.','configurationform'),
                        'name' => AddonPaymentsConfig::DEFAULT_TITLE,
                        'readonly' => true,
                        'label' => $this->module->l('Title', 'configurationform'),
                        'form_group_class' => 'default-config default' . $default_hidden,
                    ],
                    [
                        'col' => 6,
                        'type' => 'text',
                        'required' => false,
                        'lang' => true,
                        'desc' => $this->module->l('This controls the title which the user sees during checkout.', 'configurationform'),
                        'name' => AddonPaymentsConfig::TITLE,
                        'label' => $this->module->l('Title', 'configurationform'),
                        'form_group_class' => 'default-config custom' . $custom_hidden
                    ],
                    [
                        'col' => 6,
                        'type' => 'file',
                        'required' => false,
                        'image' => '<img src="'. ($image_default_uri ?? $empty) .'" class="imgm img-thumbnail"/>',
                        'desc' => $this->module->l('This controls the payment logo which the user sees during checkout.', 'configurationform'),
                        'name' => AddonPaymentsConfig::DEFAULT_LOGO,
                        'label' => $this->module->l('Logo', 'configurationform'),
                        'form_group_class' => 'default-config default' . $default_hidden
                    ],
                    [
                        'col' => 6,
                        'type' => 'file',
                        'required' => false,
                        'image' => $image ?? false,
                        'delete_url' => $delete_url ?? false,
                        'desc' => $this->module->l('This controls the payment logo which the user sees during checkout. Allowed formats are: .gif, .jpg, .png.', 'configurationform'),
                        'name' => AddonPaymentsConfig::LOGO,
                        'label' => $this->module->l('Logo', 'configurationform'),
                        'form_group_class' => 'default-config custom' . $custom_hidden
                    ],
                    [
                      'col' => 3,
                      'type' => 'text',
                      'required' => true,
                      'prefix' => '<i class="icon icon-lock"></i>',
                      'desc' => $this->module->l('This value will be encrypted once stored in your database.', 'configurationform'),
                      'name' => AddonPaymentsConfig::MERCHANT_ID,
                      'label' => $this->module->l('Merchant ID', 'configurationform'),
                    ],
                    [
                      'col' => 6,
                      'type' => 'text',
                      'required' => true,
                      'prefix' => '<i class="icon icon-lock"></i>',
                      'desc' => $this->module->l('This value will be encrypted once stored in your database.', 'configurationform'),
                      'name' => AddonPaymentsConfig::MERCHANT_KEY,
                      'label' => $this->module->l('API Key', 'configurationform'),
                    ],
                    [
                      'col' => 6,
                      'type' => 'text',
                      'required' => true,
                      'prefix' => '<i class="icon icon-lock"></i>',
                      'desc' => $this->module->l('This value will be encrypted once stored in your database.', 'configurationform'),
                      'name' => AddonPaymentsConfig::MERCHANT_PASSWORD,
                      'label' => $this->module->l('Password', 'configurationform'),
                    ],
                    [
                      'col' => 3,
                      'type' => 'text',
                      'required' => true,
                      'desc' => $this->module->l('This is the product ID provided to you by gateway support team.', 'configurationform'),
                      'name' => AddonPaymentsConfig::EPG_PRODUCT_ID,
                      'label' => $this->module->l('Product ID', 'configurationform'),
                    ],
                    [
                      'type' => 'switch',
                      'label' => $this->module->l('Authorize and capture all purchases', 'configurationform'),
                      'name' => AddonPaymentsConfig::SETTLE,
                      'is_bool' => true,
                      'desc' => $this->module->l('If checked, all purchases will be authorized and captured automatically on payment step during checkout. If unchecked, purchases will be only authorized to be captured later. To know more about capturing purchases check the documentation.', 'configurationform'),
                      'values' => [
                            [
                                'id' => 'active_on',
                                'value' => true,
                                'label' => $this->module->l('Authorize and capture', 'configurationform'),
                            ],
                            [
                                'id' => 'active_off',
                                'value' => false,
                                'label' => $this->module->l('Authorize only', 'configurationform'),
                            ],
                        ],
                    ],
                    [
                        'type' => 'html',
                        'name' => '',
                        'label' => $this->module->l('Financing','configurationform'),
                        'desc' => $this->module->l('Only applies if the CaixaBank Payments & Consumer (CPC) "Quix" financing payment service has been activated and contracted. Service that connects buyers and financing services. Allows you to configure payment in instalments (up to 12 months).','configurationform'),
                        'class' => 'ap-full-width ap-col-lg-3',
                    ],
                    [
                      'type' => 'select',
                      'label' => $this->module->l('Financing banner position','configurationform'),
                      'name' => AddonPaymentsConfig::BANNER_POSITION,
                      'desc' => sprintf($this->module->l('This controls the banner position on product page. If some elements added by other modules are displayed on the same hook, you can manage their positions via %s« Design - Positions »%s.', 'configurationform'),
                        '<a href="'.$this->context->link->getAdminLink('AdminModulesPositions').'">', '</a>'),
                      'class' => 'ap-full-width ap-col-lg-3',
                      'options' => [
                            'query' => [
                                [
                                    'id_option' => 1,
                                    'name' => $this->module->l('Below the product price', 'configurationform') . ' (Hook: displayProductPriceBlock)',
                                ],
                                [
                                    'id_option' => 2,
                                    'name' => $this->module->l('Below the add to cart button','configurationform') . ' (Hook: '.$hook.')',
                                ],

                            ],
                            'id' => 'id_option',
                            'name' => 'name'
                        ],
                    ],
                    [
                      'type' => 'color',
                      'label' => $this->module->l('Financing banner color','configurationform'),
                      'name' => AddonPaymentsConfig::BANNER_STYLE_COLOR,
                      'desc' => $this->module->l('This color will be used to customize some elements of the banner.', 'configurationform').'</a>'
                    ],
                    [
                      'col' => 3,
                      'type' => 'select',
                      'label' => $this->module->l('Financing banner variant','configurationform'),
                      'name' => AddonPaymentsConfig::BANNER_STYLE_VARIANT,
                      'options' => [
                            'query' => [
                                [
                                    'id_option' => 'text_banner',
                                    'name' => $this->module->l('Text Banner', 'configurationform'),
                                ],
                                [
                                    'id_option' => 'text',
                                    'name' => $this->module->l('Text','configurationform'),
                                ],
                                 [
                                    'id_option' => 'select',
                                    'name' => $this->module->l('Select','configurationform'),
                                ],
                                 [
                                    'id_option' => 'select_banner',
                                    'name' => $this->module->l('Select Banner','configurationform'),
                                ],

                            ],
                            'id' => 'id_option',
                            'name' => 'name'
                        ],
                    ],
                    [
                      'col' => 3,
                      'type' => 'select',
                      'label' => $this->module->l('Financing style branding','configurationform'),
                      'name' => AddonPaymentsConfig::BANNER_STYLE_BRANDING,
                      'desc' => $this->module->l('', 'configurationform').'</a>',
                      'options' => [
                            'query' => [
                                [
                                    'id_option' => 'lending_hub',
                                    'name' => $this->module->l('Lending hub', 'configurationform'),
                                ],

                            ],
                            'id' => 'id_option',
                            'name' => 'name'
                        ],
                    ],
                    [
                        'col' => 3,
                        'type' => 'text',
                        'lang' => true,
                        'prefix' => '<i class="icon icon-link"></i>',
                        'desc' => $this->module->l('The URL to where the user will be redirected to on successful payments.', 'configurationform'),
                        'name' => AddonPaymentsConfig::SUCCESS_URL,
                        'label' => $this->module->l('(optional) Success URL', 'configurationform'),
                    ],
                    [
                        'col' => 3,
                        'type' => 'text',
                        'lang' => true,
                        'prefix' => '<i class="icon icon-link"></i>',
                        'desc' => $this->module->l('The URL to where the user will be redirected to when user cancel the payment.', 'configurationform'),
                        'name' => AddonPaymentsConfig::CANCEL_URL,
                        'label' => $this->module->l('(optional) Cancel URL', 'configurationform'),
                    ],
                    [
                        'col' => 3,
                        'type' => 'text',
                        'lang' => true,
                        'prefix' => '<i class="icon icon-link"></i>',
                        'desc' => $this->module->l('The URL to where the user will be redirected to on failed payments.', 'configurationform'),
                        'name' => AddonPaymentsConfig::FAILURE_URL,
                        'label' => $this->module->l('(optional) Failure URL', 'configurationform'),
                    ],
                    [
                      'type' => 'select',
                      'required' => true,
                      'desc' => $this->module->l('Select the applied styling for the payment form.', 'configurationform'),
                      'name' => AddonPaymentsConfig::EPG_STYLE,
                      'label' => $this->module->l('Style', 'configurationform'),
                      'options' => [
                            'query' => [
                                [
                                    'id_option' => EPGJs::EPGJS_STYLE_DEFAULT,
                                    'name' => $this->module->l('Default', 'configurationform'),
                                ],
                                [
                                    'id_option' => EPGJs::EPGJS_STYLE_BOOTSTRAP,
                                    'name' => $this->module->l('Bootstrap', 'configurationform'),
                                ],
                            ],
                            'id' => 'id_option',
                            'name' => 'name',
                        ],
                    ],
                    [
                      'type' => 'hidden',
                      'name' => AddonPaymentsConfig::PRINTED_KEY,
                    ],
                ],
                'submit' => [
                    'title' => $this->module->l('Save', 'configurationform'),
                    'class' => 'btn btn-default pull-right',
                ],
            ],
        ];
    }

    public function postProcess(): bool
    {
        if('1' === Tools::getValue('delete_image')){
            $this->deteleImage();
        }

        if (true !== Tools::isSubmit($this->getSubmitName())) {
            return false;
        }

        $values = $this->getValues();
        $encryptionKey = self::getEncryptionKey();
        $encrypted = [
          AddonPaymentsConfig::MERCHANT_ID,
          AddonPaymentsConfig::MERCHANT_KEY,
          AddonPaymentsConfig::MERCHANT_PASSWORD,
        ];

        $translated = [];
        $languages = Language::getLanguages(true, false, true);

        foreach ($languages as $idLanguage) {
            foreach (
                [
                    AddonPaymentsConfig::TITLE,
                    AddonPaymentsConfig::SUCCESS_URL,
                    AddonPaymentsConfig::FAILURE_URL,
                    AddonPaymentsConfig::CANCEL_URL,
                ] as $translated_key
            ) {
                $translated["{$translated_key}_{$idLanguage}"] = $translated_key;
            }
        }


        foreach (array_keys($values) as $key) {
            // Translations need to be handled later.
            if (array_key_exists($key, $translated)) {
                continue;
            }

            //No need to save
            if(AddonPaymentsConfig::DEFAULT_TITLE === $key || AddonPaymentsConfig::DEFAULT_LOGO === $key) {
                continue;
            }

            $value = Tools::getValue($key);

            if (in_array($key, $encrypted, true)) {
                $value = $this->encrypt($value, $encryptionKey);
            }
            // If submitted the printed key is always true.
            if (AddonPaymentsConfig::PRINTED_KEY === $key) {
                $value = true;
            }

            Configuration::updateValue($key, $value);
        }

        // Handle translatable configs.
        $translatedValues = [];
        foreach ($translated as $formKey => $configKey) {
            if (!array_key_exists($configKey, $translatedValues)) {
                $translatedValues[$configKey] = [];
            }

            $parts = explode('_', $formKey);
            $id_language = array_pop($parts);

            if(AddonPaymentsConfig::DEFAULT_OPTION_CUSTOM !== Tools::getValue(AddonPaymentsConfig::DEFAULT_CONFIGURATION)) {
                $translatedValues[$configKey] += [
                    $id_language => '',
                ];
            }else {
                $translatedValues[$configKey] += [
                    $id_language => Tools::getValue($formKey),
                ];
            }

        }

        foreach ($translatedValues as $key => $translatedValue) {
            Configuration::updateValue($key, $translatedValue);
        }

        //Handle Custom Logo
        if(AddonPaymentsConfig::DEFAULT_OPTION_CUSTOM !== Tools::getValue(AddonPaymentsConfig::DEFAULT_CONFIGURATION)) {
            Configuration::updateValue(AddonPaymentsConfig::LOGO, '');
        }else {

            if (isset($_FILES[AddonPaymentsConfig::LOGO]['tmp_name'])
                && !empty($_FILES[AddonPaymentsConfig::LOGO]['tmp_name'])
            ) {
                if ($error = ImageManager::validateUpload($_FILES[AddonPaymentsConfig::LOGO], 4000000)) {
                     $this->context->controller->errors[] = $error;
                } else {
                    $file_name = $_FILES[AddonPaymentsConfig::LOGO]['name'];
                    $images_dir = $this->module->getLocalPath().'img';

                    if (!file_exists($images_dir)) {
                        mkdir($images_dir, 0755, true);
                    }

                    if (!move_uploaded_file(
                        $_FILES[AddonPaymentsConfig::LOGO]['tmp_name'],
                        $images_dir.DIRECTORY_SEPARATOR.$file_name
                    )
                    ) {
                        return  $this->context->controller->errors[] =
                            $this->l('An error occurred while attempting to upload the file.', [], 'Admin.Notifications.Error');
                    }

                    Configuration::updateValue(AddonPaymentsConfig::LOGO, $file_name);
                }
            } else {
                Configuration::updateValue(AddonPaymentsConfig::LOGO, $values[AddonPaymentsConfig::LOGO]);
            }
        }


        $this->tpl_vars['fields_value'] = $this->getValues();

        if(!empty($this->context->controller->errors)) {
            return false;
        }

        return true;
    }

    /**
     * Remove Addonpayments current image
     *
     * @return void
     */
    private function deteleImage()
    {
        $current_image = Configuration::get(AddonPaymentsConfig::LOGO);

        if (empty($current_image)) {
            return;
        }

        $images_dir = $this->module->getLocalPath().'img';
        $filename = $images_dir.DIRECTORY_SEPARATOR.$current_image;
        Configuration::updateValue(AddonPaymentsConfig::LOGO, null);

        if (is_file($filename) && file_exists($filename)) {
            unlink($filename);
        }
    }
}
