<?php /** @noinspection PhpMultipleClassDeclarationsInspection */
/*
 *   $Id$
 *
 *   AbanteCart, Ideal OpenSource Ecommerce Solution
 *   http://www.AbanteCart.com
 *
 *   Copyright © 2011-2025 Belavier Commerce LLC
 *
 *   This source file is subject to Open Software License (OSL 3.0)
 *   License details are bundled with this package in the file LICENSE.txt.
 *   It is also available at this URL:
 *   <http://www.opensource.org/licenses/OSL-3.0>
 *
 *  UPGRADE NOTE:
 *    Do not edit or add to this file if you wish to upgrade AbanteCart to newer
 *    versions in the future. If you wish to customize AbanteCart for your
 *    needs, please refer to http://www.AbanteCart.com for more information.
 */
if (!defined('DIR_CORE')) {
    header('Location: static_pages/');
}

/**
 * @property AExtensionManager $extension_manager
 * @property ASession $session
 * @property ALanguageManager $language
 * @property ALoader $load
 * @property AIMManager $im
 * @property AConfig $config
 * @property ARequest $request
 * @property ExtensionsApi $extensions
 */
class AConfigManager
{
    /** comma-separated alert emails regex pattern  */
    const ALERT_EMAILS_REGEX = '/^([A-Z0-9._%-]+@[A-Z0-9.-]{0,61}[A-Z0-9]\.[A-Z]{2,16}(,)*(\s)*)*$/i';
    protected $registry;
    protected $groups = [];
    protected $templates = [];
    public $data = [];
    public $errors = [];
    /** @var ModelSettingSetting */
    protected $mdl;

    public function __construct()
    {
        if (!IS_ADMIN) { // forbid for non-admin calls
            throw new AException (AC_ERR_LOAD, 'Error: permission denied to access class AConfigManager');
        }
        $this->registry = Registry::getInstance();
        $this->mdl = $this->load->model('setting/setting');
        $this->groups = $this->config->groups;
    }

    public function __get($key)
    {
        return $this->registry->get($key);
    }

    public function __set($key, $value)
    {
        $this->registry->set($key, $value);
    }

    /**
     *    Build field for provided key setting
     *
     * @param string $setting_key
     * @param AForm $form - form object where filed will be shown
     * @param array $data - current setting data
     * @param int $store_id - Selected store ID for the setting
     * @param string $group
     *
     * @return array
     * @throws AException
     */
    public function getFormField($setting_key, $form, $data, $store_id, $group = '')
    {
        //locate setting group first
        if (!$group) {
            $group = $this->mdl->getSettingGroup($setting_key, $store_id);
            $group = $group[0];
        }
        //set template id to get settings for default template in appearance section
        if ($group == 'appearance') {
            $data['tmpl_id'] = 'default';
        }
        $data['one_field'] = $setting_key;
        return $this->getFormFields($group, $form, $data);
    }

    /**
     *    Build fields array for provided setting group (section)
     *
     * @param string $group
     * @param AForm $form - form object where filed will be shown
     * @param array $data - current setting data
     *
     * @return array
     */
    public function getFormFields($group, $form, $data)
    {
        /** @see _build_form_details() */
        /** @see _build_form_general() */
        /** @see _build_form_checkout() */
        /** @see _build_form_appearance() */
        /** @see _build_form_mail() */
        /** @see _build_form_im() */
        /** @see _build_form_api() */
        /** @see _build_form_system() */
        $method_name = "_build_form_" . $group;
        if (!method_exists($this, $method_name)) {
            return [];
        }

        $this->data['fields'] = $this->$method_name($form, $data);
        $this->extensions->hk_ProcessData($this, $method_name, $data);
        return $this->data['fields'];
    }

    /**
     * @param string $group
     * @param array|null $data
     * @param int|null $store_id
     * @return array|false
     * @throws AException
     */
    public function validate(string $group, ?array $data = [], ?int $store_id = 0)
    {
        if (!$group || !$data) {
            return false;
        }
        $this->load->language('setting/setting');
        $this->errors = [];
        foreach ($data as $dataName => $dataValue) {
            switch ($group) {
                case 'details':
                    $config_url = $config_ssl_url = '';
                    if ($dataName == 'store_name' && !$dataValue) {
                        $this->errors['name'] = $this->language->get('error_name');
                    }
                    if ($dataName == 'config_title' && !$dataValue) {
                        $this->errors['title'] = $this->language->get('error_title');
                    }
                    //URLS validation
                    if ($dataName == 'config_url' && $dataValue) {
                        $config_url = $dataValue;
                    }
                    if ($dataName == 'config_ssl_url' && $dataValue) {
                        $config_ssl_url = $dataValue;
                    }
                    if ($dataName == 'config_url'
                        && (!$dataValue
                            || !preg_match("/^(http|https):\/\//", $dataValue))
                    ) {
                        $this->errors['url'] = $this->language->get('error_url');
                    }
                    if ($dataName == 'config_ssl_url' && $dataValue
                        && !preg_match("/^(http|https):\/\//", $dataValue)
                    ) {
                        $this->errors['ssl_url'] = $this->language->get('error_ssl_url');
                    } //when quicksave only ssl_url
                    elseif ($dataName == 'config_ssl_url' && $dataValue && !has_value($data['config_url'])) {
                        $saved_settings = $this->mdl->getSetting($group, $store_id);
                        $config_url = $saved_settings['config_url'];
                        $config_ssl_url = $dataValue;
                    } //when quicksave only url
                    elseif ($dataName == 'config_url' && $dataValue && !has_value($data['config_ssl_url'])) {
                        $saved_settings = $this->mdl->getSetting($group, $store_id);
                        $config_ssl_url = $saved_settings['config_ssl_url'];
                        $config_url = $dataValue;
                    }
                    //When store url is secure but ssl_url not - show error
                    if (!$this->errors['url']
                        && !$this->errors['ssl_url']
                        && preg_match("/^(https):\/\//", $config_url)
                        && preg_match("/^(http):\/\//", $config_ssl_url)
                    ) {
                        $this->errors['ssl_url'] = $this->language->get('error_ssl_url');
                    }

                    if (isset($data['config_owner'])
                        && (
                            mb_strlen($data['config_owner']) < 2
                            || mb_strlen($data['config_owner']) > 64
                        )
                    ) {
                        $this->errors['owner'] = $this->language->get('error_owner');
                    }

                    if (isset($data['config_address'])
                        && (
                            mb_strlen($data['config_address']) < 2
                            || mb_strlen($data['config_address']) > 256
                        )
                    ) {
                        $this->errors['address'] = $this->language->get('error_address');
                    }

                    if (isset($data['store_main_email'])
                        && (
                            mb_strlen($data['store_main_email']) > 96
                            || (!preg_match(EMAIL_REGEX_PATTERN, $data['store_main_email']))
                        )
                    ) {
                        $this->errors['email'] = $this->language->get('error_email');
                    }

                    if (isset($data['config_telephone']) && mb_strlen($data['config_telephone']) > 32) {
                        $this->errors['telephone'] = $this->language->get('error_telephone');
                    }
                    if (isset($data['config_postcode']) && mb_strlen($data['config_postcode']) < 3) {
                        $this->errors['postcode'] = $this->language->get('error_postcode');
                    }
                    if (isset($data['config_city']) && mb_strlen($data['config_city']) < 2) {
                        $this->errors['city'] = $this->language->get('error_city');
                    }
                    break;
                case 'appearance':
                    $item_name = [
                        'thumb',
                        'popup',
                        'category',
                        'manufacturer',
                        'product',
                        'additional',
                        'related',
                        'cart',
                        'grid',
                    ];
                    foreach ($item_name as $key) {
                        foreach (['width', 'height'] as $dim) {
                            if ($dataName == 'config_image_' . $key . '_' . $dim && !$dataValue) {
                                $this->errors['image_' . $key . '_' . $dim] = $this->language->get('error_image_' . $key);
                            }
                        }
                    }

                    $item_name = [
                        'catalog_limit',
                        'bestseller_limit',
                        'featured_limit',
                        'latest_limit',
                        'special_limit',
                        'content_limit',
                    ];
                    foreach ($item_name as $name) {
                        if ($dataName == 'config_' . $name && !$dataValue) {
                            $this->errors[$name] = $this->language->get('error_limit');
                        }
                    }

                    break;

                case 'checkout':
                    if ($dataName == 'config_start_order_id' && $dataValue && !(int)$dataValue) {
                        $this->errors['start_order_id'] = $this->language->get('error_start_order_id');
                    }
                    if ($dataName == 'starting_invoice_id' && $dataValue && !(int)$dataValue) {
                        $this->errors['starting_invoice_id'] = $this->language->get('error_starting_invoice_id');
                    }
                    if ($dataName == 'config_expire_order_days' && $dataValue && !(int)$dataValue) {
                        $this->errors['expire_order_days'] = $this->language->get('error_expire_order_days');
                    }
                    break;

                case 'mail':
                    if (($data['config_mail_protocol'] == 'smtp')
                        && (($dataName == 'config_smtp_host' && !$dataValue)
                            || ($dataName == 'config_smtp_port' && !$dataValue)
                            || ($dataName == 'config_smtp_timeout' && !$dataValue))
                    ) {
                        $this->errors['mail'] = $this->language->get('error_mail');
                    }

                    if ($dataName == 'config_alert_emails'
                        && $dataValue
                        && !preg_match(self::ALERT_EMAILS_REGEX, $dataValue)
                    ) {
                        $this->errors['alert_emails'] = $this->language->get('error_alert_emails');
                    }
                    break;

                case 'system':
                    if ($dataName == 'config_error_filename' && !$dataValue) {
                        $this->errors['error_filename'] = $this->language->get('error_error_filename');
                    }
                    if ($dataName == 'config_upload_max_size') {
                        $data[$dataValue] = preformatInteger($dataValue);
                    }
                    break;
                default:
                    break;
            }
        }
        $this->extensions->hk_ValidateData($this, func_get_args());
        return ['error' => $this->errors, 'validated' => $data];
    }

    /**
     * @param AForm $form
     * @param array $data
     *
     * @return array
     * @throws AException
     *
     */
    protected function _build_form_details($form, $data)
    {
        $language_id = $this->language->getContentLanguageID();
        $fields = $props = [];
        // details section
        $fields['name'] = $form->getFieldHtml(
            $props[] = [
                'type'     => 'input',
                'name'     => 'store_name',
                'value'    => $data['store_name'],
                'required' => true,
                'style'    => 'large-field',
            ]
        );
        $fields['url'] = $form->getFieldHtml(
            $props[] = [
                'type'     => 'input',
                'name'     => 'config_url',
                'value'    => $data['config_url'],
                'required' => true,
                'style'    => 'large-field',
            ]
        );
        $fields['ssl_url'] = $form->getFieldHtml(
            $props[] = [
                'type'     => 'input',
                'name'     => 'config_ssl_url',
                'value'    => $data['config_ssl_url'],
                'required' => true,
                'style'    => 'large-field',
            ]
        );
        $fields['title'] = $form->getFieldHtml(
            $props[] = [
                'type'         => 'input',
                'name'         => 'config_title_' . $language_id,
                'value'        => $data['config_title_' . $language_id],
                'required'     => true,
                'style'        => 'large-field',
                'multilingual' => true,
            ]
        );
        $fields['meta_description'] = $form->getFieldHtml(
            $props[] = [
                'type'         => 'textarea',
                'name'         => 'config_meta_description_' . $language_id,
                'value'        => $data['config_meta_description_' . $language_id],
                'style'        => 'large-field',
                'multilingual' => true,
            ]
        );
        $fields['meta_keywords'] = $form->getFieldHtml(
            $props[] = [
                'type'         => 'textarea',
                'name'         => 'config_meta_keywords_' . $language_id,
                'value'        => $data['config_meta_keywords_' . $language_id],
                'style'        => 'large-field',
                'multilingual' => true,
            ]
        );
        $fields['description'] = $form->getFieldHtml(
            $props[] = [
                'type'         => 'texteditor',
                'name'         => 'config_description_' . $language_id,
                'value'        => $data['config_description_' . $language_id],
                'style'        => 'xl-field',
                'multilingual' => true,
            ]
        );
        $fields['owner'] = $form->getFieldHtml(
            $props[] = [
                'type'     => 'input',
                'name'     => 'config_owner',
                'value'    => $data['config_owner'],
                'required' => true,
                'style'    => 'large-field',
            ]
        );

        $fields['postcode'] = $form->getFieldHtml(
            $props[] = [
                'type'     => 'input',
                'name'     => 'config_postcode',
                'value'    => $data['config_postcode'],
                'required' => true,
                'style'    => 'tiny-field',
            ]
        );

        $fields['address'] = $form->getFieldHtml(
            $props[] = [
                'type'     => 'textarea',
                'name'     => 'config_address',
                'value'    => $data['config_address'],
                'required' => true,
                'style'    => 'large-field',
            ]
        );

        $fields['city'] = $form->getFieldHtml(
            $props[] = [
                'type'     => 'input',
                'name'     => 'config_city',
                'value'    => $data['config_city'],
                'required' => true,
                'style'    => 'medium-field',
            ]
        );

        $fields['country'] = $form->getFieldHtml(
            $props[] = [
                'type'            => 'zones',
                'name'            => 'config_country_id',
                'value'           => $data['config_country_id'],
                'zone_field_name' => 'config_zone_id',
                'zone_value'      => $data['config_zone_id'],
                'submit_mode'     => 'id',
            ]
        );

        $fields['latitude'] = $form->getFieldHtml(
            $props[] = [
                'type'  => 'input',
                'name'  => 'config_latitude',
                'value' => $data['config_latitude'],
                'style' => 'medium-field',
            ]
        );

        $fields['longitude'] = $form->getFieldHtml(
            $props[] = [
                'type'  => 'input',
                'name'  => 'config_longitude',
                'value' => $data['config_longitude'],
                'style' => 'medium-field',
            ]
        );

        $fields['email'] = $form->getFieldHtml(
            $props[] = [
                'type'     => 'input',
                'name'     => 'store_main_email',
                'value'    => $data['store_main_email'],
                'required' => true,
                'style'    => 'large-field',
            ]
        );
        $fields['telephone'] = $form->getFieldHtml(
            $props[] = [
                'type'  => 'input',
                'name'  => 'config_telephone',
                'value' => $data['config_telephone'],
                'style' => 'medium-field',
            ]
        );
        $fields['fax'] = $form->getFieldHtml(
            $props[] = [
                'type'  => 'input',
                'name'  => 'config_fax',
                'value' => $data['config_fax'],
                'style' => 'medium-field',
            ]
        );

        $days = daysOfWeekList();
        $h = 0;
        $times = ['' => '--:--'];
        while ($h < 24) {
            $times[$h . ":00"] = $h . ":00";
            $h++;
        }

        foreach ($days as $day) {
            foreach (['opens', 'closes'] as $state) {
                if (!isset($data['config_opening_' . $day . '_' . $state])) {
                    $value = $state == 'opens' ? '9:00' : '21:00';
                } else {
                    $value = $data['config_opening_' . $day . '_' . $state];
                }

                $fields['opening_' . $day . '_' . $state] = $form->getFieldHtml(
                    $props[] = [
                        'type'    => 'selectbox',
                        'name'    => 'config_opening_' . $day . '_' . $state,
                        'options' => $times,
                        'value'   => $value,
                    ]
                );
            }
        }

        $results = $this->language->getAvailableLanguages();
        $languages = $language_codes = [];
        foreach ($results as $v) {
            $languages[$v['code']] = $v['name'];
            $lng_code = $this->language->getLanguageCodeByLocale((string)$v['locale']);
            $language_codes[$lng_code] = $v['name'];
        }

        /** @var ModelLocalisationCurrency $mdl */
        $mdl = $this->load->model('localisation/currency');
        $currencies = array_column($mdl->getCurrencies(), 'title', 'code');

        /** @var ModelLocalisationLengthClass $mdl */
        $mdl = $this->load->model('localisation/length_class');
        $length_classes = array_column($mdl->getLengthClasses(), 'title', 'unit');

        /** @var ModelLocalisationWeightClass $mdl */
        $mdl = $this->load->model('localisation/weight_class');
        $weight_classes = array_column($mdl->getWeightClasses(), 'title', 'unit');

        /** @var ModelLocalisationTaxClass $mdl */
        $mdl = $this->load->model('localisation/tax_class');
        $tax_classes = array_merge(
            ['' => $this->language->get('text_select')],
            array_column($mdl->getTaxClasses(), 'title', 'tax_class_id')
        );


        $fields['duplicate_contact_us'] = $form->getFieldHtml(
            $props[] = [
                'type'  => 'checkbox',
                'name'  => 'config_duplicate_contact_us_to_message',
                'value' => $data['config_duplicate_contact_us_to_message'],
                'style' => 'btn_switch',
            ]
        );

        $fields['language'] = $form->getFieldHtml(
            $props[] = [
                'type'    => 'selectbox',
                'name'    => 'config_storefront_language',
                'value'   => $data['config_storefront_language'],
                'options' => $languages,
            ]
        );

        $fields['admin_language'] = $form->getFieldHtml(
            $props[] = [
                'type'    => 'selectbox',
                'name'    => 'admin_language',
                'value'   => $data['admin_language'],
                'options' => $languages,
            ]
        );

        $fields['auto_translate_status'] = $form->getFieldHtml(
            $props[] = [
                'type'  => 'checkbox',
                'name'  => 'auto_translate_status',
                'value' => $data['auto_translate_status'],
                'style' => 'btn_switch',
            ]
        );

        $fields['translate_src_lang_code'] = $form->getFieldHtml(
            $props[] = [
                'type'    => 'selectbox',
                'name'    => 'translate_src_lang_code',
                'value'   => $data['translate_src_lang_code'],
                'options' => $language_codes,
            ]
        );

        $translate_methods = $this->language->getTranslationMethods();
        $fields['translate_method'] = $form->getFieldHtml(
            $props[] = [
                'type'    => 'selectbox',
                'name'    => 'translate_method',
                'value'   => $data['translate_method'],
                'options' => $translate_methods,
            ]
        );

        $fields['translate_override_existing'] = $form->getFieldHtml(
            $props[] = [
                'type'  => 'checkbox',
                'name'  => 'translate_override_existing',
                'value' => $data['translate_override_existing'],
                'style' => 'btn_switch',
            ]
        );
        $fields['warn_lang_text_missing'] = $form->getFieldHtml(
            $props[] = [
                'type'  => 'checkbox',
                'name'  => 'warn_lang_text_missing',
                'value' => $data['warn_lang_text_missing'],
                'style' => 'btn_switch',
            ]
        );

        $fields['currency'] = $form->getFieldHtml(
            $props[] = [
                'type'    => 'selectbox',
                'name'    => 'config_currency',
                'value'   => $data['config_currency'],
                'options' => $currencies,
            ]
        );
        $fields['currency_auto'] = $form->getFieldHtml(
            $props[] = [
                'type'  => 'checkbox',
                'name'  => 'config_currency_auto',
                'value' => $data['config_currency_auto'],
                'style' => 'btn_switch',
            ]
        );
        $fields['length_class'] = $form->getFieldHtml(
            $props[] = [
                'type'    => 'selectbox',
                'name'    => 'config_length_class',
                'value'   => $data['config_length_class'],
                'options' => $length_classes,
            ]
        );

        $fields['weight_class'] = $form->getFieldHtml(
            $props[] = [
                'type'    => 'selectbox',
                'name'    => 'config_weight_class',
                'value'   => $data['config_weight_class'],
                'options' => $weight_classes,
            ]
        );

        $fields['tax_class'] = $form->getFieldHtml(
            $props[] = [
                'type'    => 'selectbox',
                'name'    => 'config_tax_class_id',
                'value'   => $data['config_tax_class_id'],
                'options' => $tax_classes,
            ]
        );

        if (isset($data['one_field'])) {
            $fields = $this->_filterField($fields, $props, $data['one_field']);
        }
        return $fields;
    }

    protected function _filterField($fields, $props, $field_name)
    {
        $output = [];
        foreach ($props as $n => $properties) {
            //for multilingual settings
            if (preformatTextID($field_name) == preformatTextID($properties['name'])
                || (is_int(strpos($field_name, 'config_description'))
                    && is_int(strpos($properties['name'], 'config_description')))
                || (is_int(strpos($field_name, 'config_title')) && is_int(strpos($properties['name'], 'config_title')))
                || (is_int(strpos($field_name, 'config_meta_description'))
                    && is_int(strpos($properties['name'], 'config_meta_description')))
                || (is_int(strpos($field_name, 'config_meta_keywords'))
                    && is_int(strpos($properties['name'], 'config_meta_keywords')))
            ) {
                $names = array_keys($fields);
                $name = $names[$n];
                $output = [$name => $fields[$name]];
                break;
            }
        }
        return $output;
    }

    /**
     * @param AForm $form
     * @param array $data
     *
     * @return array
     * @throws AException
     */
    protected function _build_form_general($form, $data)
    {
        $fields = [];
        //general section
        /** @var ModelLocalisationStockStatus $mdl */
        $mdl = $this->load->model('localisation/stock_status');
        $stock_statuses = array_merge(
            ['0' => $this->language->get('text_none')],
            array_column($mdl->getStockStatuses(), 'name', 'stock_status_id')
        );

        $fields['admin_limit'] = $form->getFieldHtml(
            $props[] = [
                'type'     => 'input',
                'name'     => 'config_admin_limit',
                'value'    => $data['config_admin_limit'],
                'required' => true,
                'style'    => 'small-field',
            ]
        );

        $fields['product_default_sort_order'] = $form->getFieldHtml(
            $props[] = [
                'type'    => 'selectbox',
                'name'    => 'config_product_default_sort_order',
                'value'   => $data['config_product_default_sort_order'],
                'options' => [
                    'sort_order-ASC'     => $this->language->get('text_sorting_sort_order_asc'),
                    'name-ASC'           => $this->language->get('text_sorting_name_asc'),
                    'name-DESC'          => $this->language->get('text_sorting_name_desc'),
                    'price-ASC'          => $this->language->get('text_sorting_price_asc'),
                    'price-DESC'         => $this->language->get('text_sorting_price_desc'),
                    'rating-DESC'        => $this->language->get('text_sorting_rating_desc'),
                    'rating-ASC'         => $this->language->get('text_sorting_rating_asc'),
                    'date_modified-DESC' => $this->language->get('text_sorting_date_desc'),
                    'date_modified-ASC'  => $this->language->get('text_sorting_date_asc'),
                ],
            ]
        );

        $fields['stock_display'] = $form->getFieldHtml(
            $props[] = [
                'type'  => 'checkbox',
                'name'  => 'config_stock_display',
                'value' => $data['config_stock_display'],
                'style' => 'btn_switch',
            ]
        );
        $fields['nostock_autodisable'] = $form->getFieldHtml(
            $props[] = [
                'type'  => 'checkbox',
                'name'  => 'config_nostock_autodisable',
                'value' => $data['config_nostock_autodisable'],
                'style' => 'btn_switch',
            ]
        );
        $fields['stock_status'] = $form->getFieldHtml(
            $props[] = [
                'type'    => 'selectbox',
                'name'    => 'config_stock_status_id',
                'value'   => $data['config_stock_status_id'],
                'options' => $stock_statuses,
            ]
        );
        $fields['display_reviews'] = $form->getFieldHtml(
            $props[] = [
                'type'  => 'checkbox',
                'name'  => 'display_reviews',
                'value' => $data['display_reviews'],
                'style' => 'btn_switch',
            ]
        );
        $fields['reviews'] = $form->getFieldHtml(
            $props[] = [
                'type'    => 'selectbox',
                'name'    => 'enable_reviews',
                'value'   => $data['enable_reviews'],
                'options' => [
                    0 => $this->language->get('text_review_disable'),
                    1 => $this->language->get('text_review_allow_all'),
                    2 => $this->language->get('text_review_allow_only_registered'),
                    3 => $this->language->get('text_review_allow_who_purchase'),
                ],
            ]
        );
        $fields['download'] = $form->getFieldHtml(
            $props[] = [
                'type'  => 'checkbox',
                'name'  => 'config_download',
                'value' => $data['config_download'],
                'style' => 'btn_switch',
            ]
        );

        $fields['help_links'] = $form->getFieldHtml(
            $props[] = [
                'type'  => 'checkbox',
                'name'  => 'config_help_links',
                'value' => $data['config_help_links'],
                'style' => 'btn_switch',
            ]
        );
        $fields['show_tree_data'] = $form->getFieldHtml(
            $props[] = [
                'type'  => 'checkbox',
                'name'  => 'config_show_tree_data',
                'value' => $data['config_show_tree_data'],
                'style' => 'btn_switch',
            ]
        );
        $fields['embed_status'] = $form->getFieldHtml(
            $props[] = [
                'type'  => 'checkbox',
                'name'  => 'config_embed_status',
                'value' => $data['config_embed_status'],
                'style' => 'btn_switch',
            ]
        );

        $fields['embed_click_action'] = $form->getFieldHtml(
            $props[] = [
                'type'    => 'selectbox',
                'name'    => 'config_embed_click_action',
                'value'   => $data['config_embed_click_action'],
                'options' => [
                    'modal'       => $this->language->get('text_embed_click_action_modal'),
                    'new_window'  => $this->language->get('text_embed_click_action_new_window'),
                    'same_window' => $this->language->get('text_embed_click_action_same_window'),
                ],
            ]
        );
        $fields['account_create_captcha'] = $form->getFieldHtml(
            $props[] = [
                'type'  => 'checkbox',
                'name'  => 'config_account_create_captcha',
                'value' => $data['config_account_create_captcha'],
                'style' => 'btn_switch',
            ]
        );

        $fields['account_recaptcha_v3'] = $form->getFieldHtml(
            $props[] = [
                'type'  => 'checkbox',
                'name'  => 'account_recaptcha_v3',
                'value' => $data['account_recaptcha_v3'],
                'style' => 'btn_switch',
            ]
        );

        $fields['recaptcha_site_key'] = $form->getFieldHtml(
            $props[] = [
                'type'  => 'input',
                'name'  => 'config_recaptcha_site_key',
                'value' => $data['config_recaptcha_site_key'],
                'style' => 'medium-field',
            ]
        );
        $fields['recaptcha_secret_key'] = $form->getFieldHtml(
            $props[] = [
                'type'  => 'input',
                'name'  => 'config_recaptcha_secret_key',
                'value' => $data['config_recaptcha_secret_key'],
                'style' => 'medium-field',
            ]
        );

        $fields['google_api_key'] = $form->getFieldHtml(
            $props[] = [
                'type'  => 'input',
                'name'  => 'config_google_api_key',
                'value' => $data['config_google_api_key'],
                'style' => 'medium-field',
            ]
        );
        $fields['google_address_autocomplete'] = $form->getFieldHtml(
            $props[] = [
                'type'  => 'checkbox',
                'name'  => 'config_google_address_autocomplete',
                'value' => $data['config_google_address_autocomplete'],
                'style' => 'btn_switch',
            ]
        );

        $fields['google_analytics'] = $form->getFieldHtml(
            $props[] = [
                'type'  => 'input',
                'name'  => 'config_google_analytics_code',
                'value' => $data['config_google_analytics_code'],
                'style' => 'medium-field',
            ]
        );

        if (isset($data['one_field'])) {
            $fields = $this->_filterField($fields, $props, $data['one_field']);
        }
        return $fields;
    }

    /**
     * @param AForm $form
     * @param array $data
     *
     * @return array
     * @throws AException
     */
    protected function _build_form_checkout($form, $data)
    {
        $fields = [];
        /** @var ModelSaleCustomerGroup $mdl */
        $mdl = $this->load->model('sale/customer_group');
        $customer_groups = array_column($mdl->getCustomerGroups(), 'name', 'customer_group_id');

        /** @var ModelLocalisationOrderStatus $mdl2 */
        $mdl2 = $this->load->model('localisation/order_status');
        $order_statuses = array_column($mdl2->getOrderStatuses(), 'name', 'order_status_id');

        $cntMnr = new AContentManager();
        $results = $cntMnr->getContents([], 'default', $this->session->data['current_store_id']);
        $contents = ['' => $this->language->get('text_none')];
        foreach ($results as $item) {
            if (!$item['status']) {
                continue;
            }
            $contents[$item['content_id']] = $item['title'];
        }

        $fields['tax'] = $form->getFieldHtml(
            $props[] = [
                'type'  => 'checkbox',
                'name'  => 'config_tax',
                'value' => $data['config_tax'],
                'style' => 'btn_switch',
            ]
        );
        $fields['tax_store'] = $form->getFieldHtml(
            $props[] = [
                'type'    => 'selectbox',
                'name'    => 'config_tax_store',
                'value'   => $data['config_tax_store'],
                'options' => [$this->language->get('entry_tax_store_0'), $this->language->get('entry_tax_store_1')],
            ]
        );
        $fields['tax_customer'] = $form->getFieldHtml(
            $props[] = [
                'type'    => 'selectbox',
                'name'    => 'config_tax_customer',
                'value'   => $data['config_tax_customer'],
                'options' => [
                    $this->language->get('entry_tax_customer_0'),
                    $this->language->get('entry_tax_customer_1'),
                ],
            ]
        );
        $fields['start_order_id'] = $form->getFieldHtml(
            $props[] = [
                'type'  => 'input',
                'name'  => 'config_start_order_id',
                'value' => $data['config_start_order_id'],
                'style' => 'small-field',
            ]
        );
        $fields['invoice'] = $form->getFieldHtml(
            $props[] = [
                'type'  => 'input',
                'name'  => 'starting_invoice_id',
                'value' => $data['starting_invoice_id'],
                'style' => 'small-field',
            ]
        );
        $fields['invoice_prefix'] = $form->getFieldHtml(
            $props[] = [
                'type'  => 'input',
                'name'  => 'invoice_prefix',
                'value' => $data['invoice_prefix'],
                'style' => 'small-field',
            ]
        );
        $fields['customer_group'] = $form->getFieldHtml(
            $props[] = [
                'type'    => 'selectbox',
                'name'    => 'config_customer_group_id',
                'value'   => $data['config_customer_group_id'],
                'options' => $customer_groups,
            ]
        );
        $fields['customer_price'] = $form->getFieldHtml(
            $props[] = [
                'type'  => 'checkbox',
                'name'  => 'config_customer_price',
                'value' => $data['config_customer_price'],
                'style' => 'btn_switch',
            ]
        );
        $fields['customer_approval'] = $form->getFieldHtml(
            $props[] = [
                'type'  => 'checkbox',
                'name'  => 'config_customer_approval',
                'value' => $data['config_customer_approval'],
                'style' => 'btn_switch',
            ]
        );
        $fields['customer_email_activation'] = $form->getFieldHtml(
            $props[] = [
                'type'  => 'checkbox',
                'name'  => 'config_customer_email_activation',
                'value' => $data['config_customer_email_activation'],
                'style' => 'btn_switch',
            ]
        );
        $fields['prevent_email_as_login'] = $form->getFieldHtml(
            $props[] = [
                'type'  => 'checkbox',
                'name'  => 'prevent_email_as_login',
                'value' => $data['prevent_email_as_login'],
                'style' => 'btn_switch',
            ]
        );
        $fields['guest_checkout'] = $form->getFieldHtml(
            $props[] = [
                'type'  => 'checkbox',
                'name'  => 'config_guest_checkout',
                'value' => $data['config_guest_checkout'],
                'style' => 'btn_switch',
            ]
        );
        $fields['unauth_customer'] = $form->getFieldHtml(
            $props[] = [
                'type'  => 'checkbox',
                'name'  => 'config_unauth_customer',
                'value' => $data['config_unauth_customer'] ?? 1,
                'style' => 'btn_switch',
            ]
        );
        $fields['account'] = $form->getFieldHtml(
            $props[] = [
                'type'    => 'selectbox',
                'name'    => 'config_account_id',
                'value'   => $data['config_account_id'],
                'options' => $contents,
            ]
        );
        $fields['checkout'] = $form->getFieldHtml(
            $props[] = [
                'type'    => 'selectbox',
                'name'    => 'config_checkout_id',
                'value'   => $data['config_checkout_id'],
                'options' => $contents,
            ]
        );
        $fields['stock_checkout'] = $form->getFieldHtml(
            $props[] = [
                'type'  => 'checkbox',
                'name'  => 'config_stock_checkout',
                'value' => $data['config_stock_checkout'],
                'style' => 'btn_switch',
            ]
        );
        $fields['total_order_maximum'] = $form->getFieldHtml(
            $props[] = [
                'type'  => 'input',
                'name'  => 'total_order_maximum',
                'value' => $data['total_order_maximum'],
                'style' => 'small-field',
            ]
        );
        $fields['total_order_minimum'] = $form->getFieldHtml(
            $props[] = [
                'type'  => 'input',
                'name'  => 'total_order_minimum',
                'value' => $data['total_order_minimum'],
                'style' => 'small-field',
            ]
        );
        $fields['order_status'] = $form->getFieldHtml(
            $props[] = [
                'type'    => 'selectbox',
                'name'    => 'config_order_status_id',
                'value'   => $data['config_order_status_id'],
                'options' => $order_statuses,
            ]
        );
        $fields['customer_cancelation_order_status'] = $form->getFieldHtml(
            $props[] = [
                'type'    => 'multiselectbox',
                'name'    => 'config_customer_cancelation_order_status_id[]',
                'value'   => $data['config_customer_cancelation_order_status_id'] ?? [],
                'options' => $order_statuses,
                'style'   => 'chosen',
            ]
        );

        $fields['expire_order_days'] = $form->getFieldHtml(
            $props[] = [
                'type'  => 'input',
                'name'  => 'config_expire_order_days',
                'value' => $data['config_expire_order_days'],
                'style' => 'small-field',
            ]
        );
        $fields['cart_weight'] = $form->getFieldHtml(
            $props[] = [
                'type'  => 'checkbox',
                'name'  => 'config_cart_weight',
                'value' => $data['config_cart_weight'],
                'style' => 'btn_switch',
            ]
        );
        $fields['shipping_session'] = $form->getFieldHtml(
            $props[] = [
                'type'  => 'checkbox',
                'name'  => 'config_shipping_session',
                'value' => $data['config_shipping_session'],
                'style' => 'btn_switch',
            ]
        );
        $fields['cart_ajax'] = $form->getFieldHtml(
            $props[] = [
                'type'  => 'checkbox',
                'name'  => 'config_cart_ajax',
                'value' => $data['config_cart_ajax'],
                'style' => 'btn_switch',
            ]
        );
        $fields['zero_customer_balance'] = $form->getFieldHtml(
            $props[] = [
                'type'  => 'checkbox',
                'name'  => 'config_zero_customer_balance',
                'value' => $data['config_zero_customer_balance'],
                'style' => 'btn_switch',
            ]
        );
        $fields['shipping_tax_estimate'] = $form->getFieldHtml(
            $props[] = [
                'type'  => 'checkbox',
                'name'  => 'config_shipping_tax_estimate',
                'value' => $data['config_shipping_tax_estimate'],
                'style' => 'btn_switch',
            ]
        );
        $fields['coupon_on_cart_page'] = $form->getFieldHtml(
            $props[] = [
                'type'  => 'checkbox',
                'name'  => 'config_coupon_on_cart_page',
                'value' => $data['config_coupon_on_cart_page'],
                'style' => 'btn_switch',
            ]
        );
        $fields['fast_checkout_allow_coupon'] = $form->getFieldHtml(
            $props[] = [
                'type'  => 'checkbox',
                'name'  => 'fast_checkout_allow_coupon',
                'value' => $data['fast_checkout_allow_coupon'],
                'style' => 'btn_switch',
            ]
        );

        $fields['fast_checkout_payment_address_equal_shipping'] = $form->getFieldHtml(
            $props[] = [
                'type'  => 'checkbox',
                'name'  => 'fast_checkout_payment_address_equal_shipping',
                'value' => $data['fast_checkout_payment_address_equal_shipping'],
                'style' => 'btn_switch',
            ]
        );
        $fields['fast_checkout_show_order_comment_field'] = $form->getFieldHtml(
            $props[] = [
                'type'  => 'checkbox',
                'name'  => 'fast_checkout_show_order_comment_field',
                'value' => $data['fast_checkout_show_order_comment_field'],
                'style' => 'btn_switch',
            ]
        );
        $fields['fast_checkout_create_account'] = $form->getFieldHtml(
            $props[] = [
                'type'  => 'checkbox',
                'name'  => 'fast_checkout_create_account',
                'value' => $data['fast_checkout_create_account'],
                'style' => 'btn_switch',
            ]
        );
        $fields['fast_checkout_buy_now_status'] = $form->getFieldHtml(
            $props[] = [
                'type'  => 'checkbox',
                'name'  => 'fast_checkout_buy_now_status',
                'value' => $data['fast_checkout_buy_now_status'],
                'style' => 'btn_switch',
            ]
        );

        if (isset($data['one_field'])) {
            $fields = $this->_filterField($fields, $props, $data['one_field']);
        }
        return $fields;
    }

    /**
     * @param AForm $form
     * @param array $data
     *
     * @return array
     * @throws AException
     */
    protected function _build_form_appearance($form, $data)
    {
        $fields = [];
        //this method ca build fields for general appearance or template specific
        //for template settings, need to specify 'tmpl_id' as template_id for settings section
        if (!$data['tmpl_id']) {
            //general appearance section
            $templates = $this->getTemplates('storefront');

            $fields['template'] = $form->getFieldHtml(
                $props[] = [
                    'type'    => 'selectbox',
                    'name'    => 'config_storefront_template',
                    'value'   => $data['config_storefront_template'],
                    'options' => $templates,
                    'style'   => 'large-field',
                ]
            );

            $templates = $this->getTemplates('admin');

            $fields['admin_template'] = $form->getFieldHtml(
                $props[] = [
                    'type'    => 'selectbox',
                    'name'    => 'admin_template',
                    'value'   => $data['admin_template'],
                    'options' => $templates,
                    'style'   => 'large-field',
                ]
            );
            $fields['admin_width'] = $form->getFieldHtml(
                $props[] = [
                    'type'     => 'input',
                    'name'     => 'admin_width',
                    'value'    => $data['admin_width'],
                    'style'    => 'small-field',
                    'required' => true,
                ]
            );
            $fields['image_grid_width'] = $form->getFieldHtml(
                $props[] = [
                    'type'     => 'input',
                    'name'     => 'config_image_grid_width',
                    'value'    => $data['config_image_grid_width'],
                    'style'    => 'small-field',
                    'required' => true,
                ]
            );
            $fields['image_grid_height'] = $form->getFieldHtml(
                $props[] = [
                    'type'     => 'input',
                    'name'     => 'config_image_grid_height',
                    'value'    => $data['config_image_grid_height'],
                    'style'    => 'small-field',
                    'required' => true,
                ]
            );
            $fields['image_product_width'] = $form->getFieldHtml(
                $props[] = [
                    'type'     => 'input',
                    'name'     => 'config_image_product_width',
                    'value'    => $data['config_image_product_width'],
                    'style'    => 'small-field',
                    'required' => true,
                ]
            );
            $fields['image_product_height'] = $form->getFieldHtml(
                $props[] = [
                    'type'     => 'input',
                    'name'     => 'config_image_product_height',
                    'value'    => $data['config_image_product_height'],
                    'style'    => 'small-field',
                    'required' => true,
                ]
            );
        } else {
            // settings per template
            $default_values = $this->mdl->getSetting('appearance', (int)$data['store_id']);
            $fieldset = [
                'storefront_width',
                'config_logo',
                'config_mail_logo',
                'config_icon',
                'config_catalog_limit',
                'config_bestseller_limit',
                'config_featured_limit',
                'config_latest_limit',
                'config_special_limit',
                'config_content_limit',
                'config_image_thumb_width',
                'config_image_thumb_height',
                'config_image_popup_width',
                'config_image_popup_height',
                'config_image_category_width',
                'config_image_category_height',
                'config_image_manufacturer_width',
                'config_image_manufacturer_height',
                'config_image_product_width',
                'config_image_product_height',
                'config_image_additional_width',
                'config_image_additional_height',
                'config_image_related_width',
                'config_image_related_height',
                'config_image_cart_width',
                'config_image_cart_height',
                'config_image_grid_width',
                'config_image_grid_height',
            ];
            $languages = $this->language->getActiveLanguages();
            $logosArr = [
                'logo'      => 'config_logo',
                'mail_logo' => 'config_mail_logo',
            ];
            if (count($languages) > 1) {
                //see if we have resource id or path
                $languageId = $data['language_id'] ?? $this->language->getContentLanguageID();
                foreach ($languages as $lang) {
                    $lId = $lang['language_id'];
                    //leave only content language
                    if ($languageId != $lId) {
                        continue;
                    }
                    $lName = mb_strtolower($lang['name']);
                    $logosArr['logo_' . $lName] = $fieldset[] = 'config_logo_' . $lId;
                    $logosArr['mail_logo_' . $lName] = $fieldset[] = 'config_mail_logo_' . $lId;
                }
            }

            foreach ($fieldset as $name) {
                if (!has_value($data[$name]) && has_value($default_values[$name])) {
                    $data[$name] = $default_values[$name];
                }
            }

            $fields['storefront_width'] = $form->getFieldHtml(
                $props[] = [
                    'type'     => 'input',
                    'name'     => 'storefront_width',
                    'value'    => $data['storefront_width'],
                    'style'    => 'small-field',
                    'required' => true,
                ]
            );
            // "default" logos + additional for language
            foreach ($logosArr as $alias => $name) {
                $defaultValue = $data[$name] ?? '';
                $p = [
                    'type'    => 'resource',
                    'name'    => $name,
                    'rl_type' => 'image',
                ];
                if (is_numeric($defaultValue) || !$defaultValue) {
                    $p['resource_id'] = $defaultValue;
                } else {
                    $p['resource_path'] = htmlspecialchars(
                        $defaultValue,
                        ENT_COMPAT,
                        'UTF-8'
                    );
                }
                $fields[$alias] = (string)$form->getFieldHtml(
                    $props[] = $p
                );
            }

            //see if we have resource id or path
            if (is_numeric($data['config_icon'])) {
                $fields['icon'] = $form->getFieldHtml(
                    $props[] = [
                        'type'        => 'resource',
                        'name'        => 'config_icon',
                        'resource_id' => $data['config_icon'],
                        'rl_type'     => 'image',
                    ]
                );
            } else {
                $fields['icon'] = $form->getFieldHtml(
                    $props[] = [
                        'type'          => 'resource',
                        'name'          => 'config_icon',
                        'resource_path' => htmlspecialchars($data['config_icon'], ENT_COMPAT, 'UTF-8'),
                        'rl_type'       => 'image',
                    ]
                );
            }

            $fields['catalog_limit'] = $form->getFieldHtml(
                $props[] = [
                    'type'     => 'input',
                    'name'     => 'config_catalog_limit',
                    'value'    => $data['config_catalog_limit'],
                    'required' => true,
                    'style'    => 'small-field',
                ]
            );

            $fields['bestseller_limit'] = $form->getFieldHtml(
                $props[] = [
                    'type'     => 'input',
                    'name'     => 'config_bestseller_limit',
                    'value'    => $data['config_bestseller_limit'],
                    'required' => true,
                    'style'    => 'small-field',
                ]
            );
            $fields['featured_limit'] = $form->getFieldHtml(
                $props[] = [
                    'type'     => 'input',
                    'name'     => 'config_featured_limit',
                    'value'    => $data['config_featured_limit'],
                    'required' => true,
                    'style'    => 'small-field',
                ]
            );
            $fields['latest_limit'] = $form->getFieldHtml(
                $props[] = [
                    'type'     => 'input',
                    'name'     => 'config_latest_limit',
                    'value'    => $data['config_latest_limit'],
                    'required' => true,
                    'style'    => 'small-field',
                ]
            );
            $fields['special_limit'] = $form->getFieldHtml(
                $props[] = [
                    'type'     => 'input',
                    'name'     => 'config_special_limit',
                    'value'    => $data['config_special_limit'],
                    'required' => true,
                    'style'    => 'small-field',
                ]
            );

            $fields['content_limit'] = $form->getFieldHtml(
                $props[] = [
                    'type'     => 'input',
                    'name'     => 'config_content_limit',
                    'value'    => $data['config_content_limit'],
                    'required' => true,
                    'style'    => 'small-field',
                ]
            );

            $fields['viewed_products_limit'] = $form->getFieldHtml(
                $props[] = [
                    'type'     => 'input',
                    'name'     => 'viewed_products_limit',
                    'value'    => $data['viewed_products_limit'],
                    'style'    => 'small-field',
                    'required' => true,
                ]
            );

            $fields['viewed_products_image_width'] = $form->getFieldHtml(
                $props[] = [
                    'type'     => 'input',
                    'name'     => 'viewed_products_image_width',
                    'value'    => $data['viewed_products_image_width'],
                    'style'    => 'small-field',
                    'required' => true,
                ]
            );
            $fields['viewed_products_image_height'] = $form->getFieldHtml(
                $props[] = [
                    'type'     => 'input',
                    'name'     => 'viewed_products_image_height',
                    'value'    => $data['viewed_products_image_height'],
                    'style'    => 'small-field',
                    'required' => true,
                ]
            );

            $fields['image_thumb_width'] = $form->getFieldHtml(
                $props[] = [
                    'type'     => 'input',
                    'name'     => 'config_image_thumb_width',
                    'value'    => $data['config_image_thumb_width'],
                    'style'    => 'small-field',
                    'required' => true,
                ]
            );

            $fields['image_thumb_height'] = $form->getFieldHtml(
                $props[] = [
                    'type'     => 'input',
                    'name'     => 'config_image_thumb_height',
                    'value'    => $data['config_image_thumb_height'],
                    'style'    => 'small-field',
                    'required' => true,
                ]
            );
            $fields['image_popup_width'] = $form->getFieldHtml(
                $props[] = [
                    'type'     => 'input',
                    'name'     => 'config_image_popup_width',
                    'value'    => $data['config_image_popup_width'],
                    'style'    => 'small-field',
                    'required' => true,
                ]
            );
            $fields['image_popup_height'] = $form->getFieldHtml(
                $props[] = [
                    'type'     => 'input',
                    'name'     => 'config_image_popup_height',
                    'value'    => $data['config_image_popup_height'],
                    'style'    => 'small-field',
                    'required' => true,
                ]
            );
            $fields['image_category_width'] = $form->getFieldHtml(
                $props[] = [
                    'type'     => 'input',
                    'name'     => 'config_image_category_width',
                    'value'    => $data['config_image_category_width'],
                    'style'    => 'small-field',
                    'required' => true,
                ]
            );
            $fields['image_category_height'] = $form->getFieldHtml(
                $props[] = [
                    'type'     => 'input',
                    'name'     => 'config_image_category_height',
                    'value'    => $data['config_image_category_height'],
                    'style'    => 'small-field',
                    'required' => true,
                ]
            );
            $fields['image_manufacturer_width'] = $form->getFieldHtml(
                $props[] = [
                    'type'     => 'input',
                    'name'     => 'config_image_manufacturer_width',
                    'value'    => $data['config_image_manufacturer_width'],
                    'style'    => 'small-field',
                    'required' => true,
                ]
            );
            $fields['image_manufacturer_height'] = $form->getFieldHtml(
                $props[] = [
                    'type'     => 'input',
                    'name'     => 'config_image_manufacturer_height',
                    'value'    => $data['config_image_manufacturer_height'],
                    'style'    => 'small-field',
                    'required' => true,
                ]
            );
            $fields['image_product_width'] = $form->getFieldHtml(
                $props[] = [
                    'type'     => 'input',
                    'name'     => 'config_image_product_width',
                    'value'    => $data['config_image_product_width'],
                    'style'    => 'small-field',
                    'required' => true,
                ]
            );
            $fields['image_product_height'] = $form->getFieldHtml(
                $props[] = [
                    'type'     => 'input',
                    'name'     => 'config_image_product_height',
                    'value'    => $data['config_image_product_height'],
                    'style'    => 'small-field',
                    'required' => true,
                ]
            );
            $fields['image_additional_width'] = $form->getFieldHtml(
                $props[] = [
                    'type'     => 'input',
                    'name'     => 'config_image_additional_width',
                    'value'    => $data['config_image_additional_width'],
                    'style'    => 'small-field',
                    'required' => true,
                ]
            );
            $fields['image_additional_height'] = $form->getFieldHtml(
                $props[] = [
                    'type'     => 'input',
                    'name'     => 'config_image_additional_height',
                    'value'    => $data['config_image_additional_height'],
                    'style'    => 'small-field',
                    'required' => true,
                ]
            );
            $fields['image_related_width'] = $form->getFieldHtml(
                $props[] = [
                    'type'     => 'input',
                    'name'     => 'config_image_related_width',
                    'value'    => $data['config_image_related_width'],
                    'style'    => 'small-field',
                    'required' => true,
                ]
            );
            $fields['image_related_height'] = $form->getFieldHtml(
                $props[] = [
                    'type'     => 'input',
                    'name'     => 'config_image_related_height',
                    'value'    => $data['config_image_related_height'],
                    'style'    => 'small-field',
                    'required' => true,
                ]
            );
            $fields['image_cart_width'] = $form->getFieldHtml(
                $props[] = [
                    'type'     => 'input',
                    'name'     => 'config_image_cart_width',
                    'value'    => $data['config_image_cart_width'],
                    'style'    => 'small-field',
                    'required' => true,
                ]
            );
            $fields['image_cart_height'] = $form->getFieldHtml(
                $props[] = [
                    'type'     => 'input',
                    'name'     => 'config_image_cart_height',
                    'value'    => $data['config_image_cart_height'],
                    'style'    => 'small-field',
                    'required' => true,
                ]
            );
            $fields['image_grid_width'] = $form->getFieldHtml(
                $props[] = [
                    'type'     => 'input',
                    'name'     => 'config_image_grid_width',
                    'value'    => $data['config_image_grid_width'],
                    'style'    => 'small-field',
                    'required' => true,
                ]
            );
            $fields['image_grid_height'] = $form->getFieldHtml(
                $props[] = [
                    'type'     => 'input',
                    'name'     => 'config_image_grid_height',
                    'value'    => $data['config_image_grid_height'],
                    'style'    => 'small-field',
                    'required' => true,
                ]
            );
        }

        $fields['image_resize_fill_color'] = $form->getFieldHtml(
            $props[] = [
                'type'  => 'color',
                'name'  => 'config_image_resize_fill_color',
                'value' => $data['config_image_resize_fill_color'] ?: '#ffffff',
                'style' => 'small-field',
            ]
        );

        if (isset($data['one_field'])) {
            $fields = $this->_filterField($fields, $props, $data['one_field']);
        }
        return $fields;
    }

    /**
     * @param string $section - can be storefront or admin
     * @param int $status - template extension status
     *
     * @return array
     * @throws AException
     */
    public function getTemplates($section, $status = 1, $store_id = 0)
    {
        if (has_value($this->templates[$section])) {
            return $this->templates[$section];
        }

        $basedir = $section == 'admin' ? DIR_APP_SECTION : DIR_STOREFRONT;

        $directories = glob($basedir . 'view/*', GLOB_ONLYDIR);
        //get core templates
        foreach ($directories as $directory) {
            $this->templates[$section][basename($directory)] = basename($directory);
        }
        if ($section != 'admin') {
            //get extension templates
            $extension_templates = $this->extension_manager->getExtensionsList(
                [
                    'filter'   => 'template',
                    'status'   => (int)$status,
                    'store_id' => $store_id ?: (int)$this->registry->get('config')->get('config_store_id'),
                ]
            );
            if ($extension_templates->total > 0) {
                foreach ($extension_templates->rows as $row) {
                    $this->templates[$section][$row['key']] = $row['key'];
                }
            }
        }

        return $this->templates[$section];
    }

    /**
     * @param AForm $form
     * @param array $data
     *
     * @return array
     * @throws AException
     */
    protected function _build_form_mail($form, $data)
    {
        $fields = [];
        //mail section
        $options = [
            'mail' => $this->language->get('text_mail'),
            'smtp' => $this->language->get('text_smtp'),
            'dsn'  => $this->language->get('text_dsn'),
        ];

        $mailExtensions = MailApiManager::getInstance()->getMailDriversList();
        foreach ($mailExtensions as $txtId => $name) {
            $options['mailapi_' . $txtId] = $name;
        }

        $fields['mail_transporting'] = $form->getFieldHtml(
            $props[] = [
                'type'    => 'selectbox',
                'name'    => 'config_mail_transporting',
                'value'   => $data['config_mail_transporting'],
                'options' => $options,
                'style'   => "no-save",
            ]
        );
        $fields['mail_parameter'] = $this->language->get('text_native_mail_description');
        $fields['smtp_host'] = $form->getFieldHtml(
            $props[] = [
                'type'     => 'input',
                'name'     => 'config_smtp_host',
                'value'    => $data['config_smtp_host'],
                'required' => true,
            ]
        );
        $fields['smtp_username'] = $form->getFieldHtml(
            $props[] = [
                'type'  => 'input',
                'name'  => 'config_smtp_username',
                'value' => $data['config_smtp_username'],
            ]
        );
        $fields['smtp_password'] = $form->getFieldHtml(
            $props[] = [
                'type'  => 'password',
                'name'  => 'config_smtp_password',
                //set five stars as value for non-required password and then do not save it in controller
                'value' => $data['config_smtp_password'],

            ]
        );
        $fields['smtp_port'] = $form->getFieldHtml(
            $props[] = [
                'type'     => 'input',
                'name'     => 'config_smtp_port',
                'value'    => $data['config_smtp_port'],
                'required' => true,
            ]
        );
        $fields['smtp_timeout'] = $form->getFieldHtml(
            $props[] = [
                'type'     => 'input',
                'name'     => 'config_smtp_timeout',
                'value'    => $data['config_smtp_timeout'],
                'required' => true,
            ]
        );

        $fields['dsn_entry'] = $this->language->get('text_dsn_description');

        $fields['alert_mail'] = $form->getFieldHtml(
            $props[] = [
                'type'  => 'checkbox',
                'name'  => 'config_alert_mail',
                'value' => $data['config_alert_mail'],
                'style' => 'btn_switch',
            ]
        );
        $fields['alert_emails'] = $form->getFieldHtml(
            $props[] = [
                'type'  => 'textarea',
                'name'  => 'config_alert_emails',
                'value' => $data['config_alert_emails'],
                'style' => 'large-field',
                'attr'  => ' pattern="' . self::ALERT_EMAILS_REGEX . '"'
            ]
        );
        if (isset($data['one_field'])) {
            $fields = $this->_filterField($fields, $props, $data['one_field']);
        }
        return $fields;
    }

    /**
     * @param AForm $form
     * @param array $data
     *
     * @return array
     * @throws AException
     */
    protected function _build_form_im($form, $data)
    {
        $fields = [];

        $protocols = $this->im->getProtocols();
        $im_drivers = $this->im->getIMDriversList();

        foreach ($protocols as $protocol) {
            //skip email protocol. it cannot be disabled
            if ($protocol == 'email') {
                continue;
            }

            if ($im_drivers[$protocol]) {
                $options = array_merge(['' => $this->language->get('text_select')], $im_drivers[$protocol]);
                $no_driver = false;
            } else {
                $options = ['' => $this->language->get('text_no_driver')];
                $no_driver = true;
            }

            $fields[$protocol]['driver'] = $form->getFieldHtml(
                $props[] = [
                    'type'    => 'selectbox',
                    'name'    => 'config_' . $protocol . '_driver',
                    'value'   => $data['config_sms_driver'],
                    'options' => $options,
                    'attr'    => $no_driver ? 'disabled' : '',
                ]
            );

            if (!$no_driver) {
                $fields[$protocol]['storefront_status'] = $form->getFieldHtml(
                    $props[] = [
                        'type'       => 'checkbox',
                        'name'       => 'config_storefront_' . $protocol . '_status',
                        'value'      => 1,
                        'checked'    => (bool)$data['config_storefront_' . $protocol . '_status'],
                        'label_text' => $this->language->get('text_storefront'),
                    ]
                );

                $fields[$protocol]['admin_status'] = $form->getFieldHtml(
                    $props[] = [
                        'type'       => 'checkbox',
                        'name'       => 'config_admin_' . $protocol . '_status',
                        'value'      => 1,
                        'checked'    => (bool)$data['config_admin_' . $protocol . '_status'],
                        'label_text' => $this->language->get('text_admin'),
                    ]
                );
            }
        }

        return $fields;
    }

    /**
     * @param AForm $form
     * @param array $data
     *
     * @return array
     * @throws AException
     */
    protected function _build_form_api($form, $data)
    {
        $fields = [];
        //api section
        $fields['storefront_api_status'] = $form->getFieldHtml(
            $props[] = [
                'type'  => 'checkbox',
                'name'  => 'config_storefront_api_status',
                'value' => $data['config_storefront_api_status'],
                'style' => 'btn_switch',
            ]
        );
        $fields['storefront_api_key'] = $form->getFieldHtml(
            $props[] = [
                'type'  => 'input',
                'name'  => 'config_storefront_api_key',
                'value' => $data['config_storefront_api_key'],
            ]
        );
        $fields['storefront_api_stock_check'] = $form->getFieldHtml(
            $props[] = [
                'type'  => 'checkbox',
                'name'  => 'config_storefront_api_stock_check',
                'value' => $data['config_storefront_api_stock_check'],
                'style' => 'btn_switch',
            ]
        );

        $fields['admin_api_status'] = $form->getFieldHtml(
            $props[] = [
                'type'  => 'checkbox',
                'name'  => 'config_admin_api_status',
                'value' => $data['config_admin_api_status'],
                'style' => 'btn_switch',
            ]
        );
        $fields['admin_api_key'] = $form->getFieldHtml(
            $props[] = [
                'type'  => 'input',
                'name'  => 'config_admin_api_key',
                'value' => $data['config_admin_api_key'],
            ]
        );
        $fields['admin_access_ip_list'] = $form->getFieldHtml(
            $props[] = [
                'type'  => 'input',
                'name'  => 'config_admin_access_ip_list',
                'value' => $data['config_admin_access_ip_list'],
                'style' => 'large-field',
            ]
        );
        $fields['task_api_key'] = $form->getFieldHtml(
            $props[] = [
                'type'  => 'input',
                'name'  => 'task_api_key',
                'value' => $data['task_api_key'],
                'style' => 'large-field',
            ]
        );

        if (isset($data['one_field'])) {
            $fields = $this->_filterField($fields, $props, $data['one_field']);
        }
        return $fields;
    }

    // validate form fields

    /**
     * @param AForm $form
     * @param array $data
     *
     * @return array
     * @throws AException
     */
    protected function _build_form_system($form, $data)
    {
        $fields = [];
        //system section
        $autoRefreshEnabled = (int)($data['config_admin_background_autorefresh'] ?? 1) === 1;
        $fields['admin_background_autorefresh'] = $form->getFieldHtml(
            $props[] = [
                'type'  => 'checkbox',
                'name'  => 'config_admin_background_autorefresh',
                'value' => $data['config_admin_background_autorefresh'] ?? 1,
                'style' => 'btn_switch',
            ]
        );
        $fields['session_ttl'] = $form->getFieldHtml(
                $props[] = [
                    'type'  => 'input',
                    'name'  => 'config_session_ttl',
                    'value' => $data['config_session_ttl'],
                    'attr'  => $autoRefreshEnabled ? 'disabled' : '',
                ]
            ) . sprintf(
                $this->language->get('text_setting_php_exceed'), 'session.gc_maxlifetime',
                (int)ini_get('session.gc_maxlifetime') / 60
            ) . '<br />'
            . $this->language->get('text_setting_session_ttl_autorefresh_note');

        $fields['maintenance'] = $form->getFieldHtml(
            $props[] = [
                'type'  => 'checkbox',
                'name'  => 'config_maintenance',
                'value' => $data['config_maintenance'],
                'style' => 'btn_switch',
            ]
        );
        $fields['voicecontrol'] = $form->getFieldHtml(
            $props[] = [
                'type'  => 'checkbox',
                'name'  => 'config_voicecontrol',
                'value' => $data['config_voicecontrol'],
                'style' => 'btn_switch',
            ]
        );
        //backwards compatibility. Can remove in the future.
        if (!defined('ENCRYPTION_KEY')) {
            $fields['encryption'] = $form->getFieldHtml(
                $props[] = [
                    'type'  => 'input',
                    'name'  => 'encryption_key',
                    'value' => $data['encryption_key'],
                    'attr'  => 'readonly',
                ]
            );
        }
        $fields['seo_url'] = $form->getFieldHtml(
            $props[] = [
                'type'  => 'checkbox',
                'name'  => 'enable_seo_url',
                'value' => $data['enable_seo_url'],
                'style' => 'btn_switch',
            ]
        );
        $fields['retina_enable'] = $form->getFieldHtml(
            $props[] = [
                'type'  => 'checkbox',
                'name'  => 'config_retina_enable',
                'value' => $data['config_retina_enable'],
                'style' => 'btn_switch',
            ]
        );
        $fields['image_quality'] = $form->getFieldHtml(
            $props[] = [
                'type'    => 'selectbox',
                'name'    => 'config_image_quality',
                'options' => [
                    10  => '10%',
                    15  => '15%',
                    20  => '20%',
                    25  => '25%',
                    30  => '30%',
                    35  => '35%',
                    40  => '40%',
                    45  => '45%',
                    50  => '50%',
                    55  => '55%',
                    60  => '60%',
                    65  => '65%',
                    70  => '70%',
                    75  => '75%',
                    80  => '80%',
                    85  => '85%',
                    90  => '90%',
                    95  => '95%',
                    100 => '100%',
                ],
                'value'   => $data['config_image_quality'],
            ]
        );

        $fields['compression'] = $form->getFieldHtml(
            $props[] = [
                'type'  => 'input',
                'name'  => 'config_compression',
                'value' => $data['config_compression'],
            ]
        );

        $all_cache_drivers = $this->registry->get('cache')->getCacheStorageDrivers();
        $cache_drivers = [];
        foreach ($all_cache_drivers as $drv) {
            $name = strtoupper($drv['driver_name']);
            $cache_drivers[$name] = $name;
        }
        sort($cache_drivers, SORT_STRING);
        $current_cache_driver = strtoupper(defined('CACHE_DRIVER') ? CACHE_DRIVER : 'file');
        unset($cache_drivers[$current_cache_driver]);

        $fields['cache_enable'] = $form->getFieldHtml(
                $props[] = [
                    'type'  => 'checkbox',
                    'name'  => 'config_cache_enable',
                    'value' => $data['config_cache_enable'],
                    'style' => 'btn_switch',
                ]
            )
            . '<br/>'
            . sprintf(
                $this->language->get('text_setting_cache_drivers'),
                $current_cache_driver,
                implode(', ', $cache_drivers)
            );

        $fields['upload_max_size'] = $form->getFieldHtml(
                $props[] = [
                    'type'  => 'input',
                    'name'  => 'config_upload_max_size',
                    'value' => (int)$data['config_upload_max_size'],
                ]
            )
            . sprintf(
                $this->language->get('text_setting_php_exceed'),
                'upload_max_filesize',
                ini_get('upload_max_filesize')
            );

        $fields['error_display'] = $form->getFieldHtml(
            $props[] = [
                'type'  => 'checkbox',
                'name'  => 'config_error_display',
                'value' => $data['config_error_display'],
                'style' => 'btn_switch',
            ]
        );
        $fields['error_log'] = $form->getFieldHtml(
            $props[] = [
                'type'  => 'checkbox',
                'name'  => 'config_error_log',
                'value' => $data['config_error_log'],
                'style' => 'btn_switch',
            ]
        );
        $fields['debug'] = $form->getFieldHtml(
            $props[] = [
                'type'    => 'selectbox',
                'name'    => 'config_debug',
                'value'   => $data['config_debug'],
                'options' => [
                    0 => $this->language->get('entry_debug_0'),
                    1 => $this->language->get('entry_debug_1'),
                    2 => $this->language->get('entry_debug_2'),
                ],
            ]
        );
        $fields['debug_level'] = $form->getFieldHtml(
            $props[] = [
                'type'    => 'selectbox',
                'name'    => 'config_debug_level',
                'value'   => $data['config_debug_level'],
                'options' => [
                    0 => $this->language->get('entry_debug_level_0'),
                    1 => $this->language->get('entry_debug_level_1'),
                    2 => $this->language->get('entry_debug_level_2'),
                    3 => $this->language->get('entry_debug_level_3'),
                    4 => $this->language->get('entry_debug_level_4'),
                    5 => $this->language->get('entry_debug_level_5'),
                ],
            ]
        );
        $fields['template_debug'] = $form->getFieldHtml(
            $props[] = [
                'type'  => 'checkbox',
                'name'  => 'storefront_template_debug',
                'value' => $data['storefront_template_debug'],
                'style' => 'btn_switch',
                'attr'  => 'reload_on_save="true"',
            ]
        );
        $fields['error_filename'] = $form->getFieldHtml(
            $props[] = [
                'type'     => 'input',
                'name'     => 'config_error_filename',
                'value'    => $data['config_error_filename'],
                'required' => true,
            ]
        );
        $fields['system_check'] = $form->getFieldHtml(
            $props[] = [
                'type'    => 'selectbox',
                'name'    => 'config_system_check',
                'value'   => $data['config_system_check'],
                'options' => [
                    0 => 'Admin & Storefront',
                    1 => 'Admin',
                    2 => 'Storefront',
                    3 => $this->language->get('text_disabled'),
                ],
            ]
        );

        $tmp = '*/5 * * * * php ' . DIR_ROOT . '/task.php > ' . DIR_LOGS . 'tasks.log 2>&1';
        $fields['cron_command'] = $form->getFieldHtml(
            $props[] = [
                'type'     => 'input',
                'name'     => 'cron_command',
                'value'    => $tmp,
                'attr'     => 'disabled data-copy="' . htmlspecialchars($tmp, ENT_QUOTES) . '"',
                'help_url' => 'https://abantecart.atlassian.net/wiki/spaces/AD/pages/15007901/Scheduled+Tasks#ScheduledTasks-CRON',
            ]
        );

        if (isset($data['one_field'])) {
            $fields = $this->_filterField($fields, $props, $data['one_field']);
        }
        return $fields;
    }

}
