<?php

namespace FiloBlu\Refilo\Model\Config;

use FiloBlu\Core\Framework\Model\Mapper;
use FiloBlu\Core\Framework\Model\MapperFactory;
use Magento\Framework\DataObject;
use Magento\Framework\DataObjectFactory;
use Magento\Framework\Exception\NoSuchEntityException;
use Magento\Framework\Module\Manager;
use Magento\Framework\Serialize\SerializerInterface;
use Magento\Store\Api\Data\StoreInterface;

/**
 * Class StoreFrontConfigProvider
 * @package FiloBlu\Refilo\Model\Config
 */
class StoreFrontConfigProvider extends AbstractConfigProvider
{
    /**
     * @var \Magento\Framework\Module\Manager
     */
    protected $moduleManager;

    /**
     * @var \Magento\Framework\Serialize\SerializerInterface
     */
    protected $serializer;

    /**
     * @param MapperFactory $mapperFactory
     * @param DataObjectFactory $dataObjectFactory
     * @param SerializerInterface $serializer
     * @param \Magento\Framework\Module\Manager $moduleManager
     */
    public function __construct(
        MapperFactory $mapperFactory,
        DataObjectFactory $dataObjectFactory,
        SerializerInterface $serializer,
        Manager $moduleManager
    ) {
        parent::__construct($mapperFactory, $dataObjectFactory);
        $this->serializer = $serializer;
        $this->moduleManager = $moduleManager;
    }

    /**
     * @param Mapper $mapper
     * @return Mapper
     */
    protected function addCatalog(Mapper $mapper)
    {
        return $mapper
            ->withDestinationRoot('storefrontConfig/catalog')
            ->add('catalog/seo/product_url_suffix', 'url_key_suffix', '')
            ->withSourceRoot('refilo_catalog/general')
            ->add('no_seo_friendly_urls', 'not_seo_friendly_urls', '')
            ->add('hide_price', 'hide_price', false, Mapper::BOOL)
            ->add('disable_shop', 'disable_shop', false, Mapper::BOOL)
            ->add('vat_label', 'vat_label', '')
            ->add('cart_vat_label', 'cart_vat_label', '')
            ->add('shipping_returns_info', 'shipping_returns_info', '')
            ->add('customer_care_info', 'customer_care_info', '')
            ->withSourceRoot('catalog/frontend')
            ->withDestinationRoot('storefrontConfig/catalog/categories')
            ->add('grid_per_page', 'products_per_page', 12, Mapper::INT)
            ->withSourceRoot('refilo_catalog/categories')
            ->add('pagination_param', 'pagination_param', '')
            ->add('sort_filter_name', 'sort_filter_name', '')
            ->add('multiple_filter_divider', 'multiple_filter_divider', '')
            ->add('history_pagination_push', 'history_pagination_push', true, Mapper::BOOL)
            ->add('history_filter_push', 'history_filter_push', true, Mapper::BOOL)
            ->add('price_filter_name', 'price_filter_name', '')
            ->add('price_filter_render', 'price_filter_render', '')
            ->add('price_filter_strategy', 'price_filter_strategy', '', Mapper::STRING)
            ->add('price_filterable_step_range', 'price_filterable_step_range', 10, Mapper::INT)
            ->add('price_filterable_price_range', 'price_filterable_price_range', 20, Mapper::INT)
            ->add('price_filterable_steps', 'price_filterable_steps', [])
            ->add('pagination_mapping', 'pagination_mapping', [])
            ->add('enable_macro_categories', 'enable_macro_categories', false, Mapper::BOOL)
            ->add('load_all_previous_products', 'load_all_previous_products', false, Mapper::BOOL)
            ->withSourceRoot('refilo_catalog/products')
            ->withDestinationRoot('storefrontConfig/catalog/products')
            ->add('image_size_width', 'image_size/width', 1000, Mapper::INT)
            ->add('image_size_height', 'image_size/height', 1000, Mapper::INT)
            ->add('use_demo_placeholder', 'use_demo_placeholder', true, Mapper::BOOL)
            ->add('enable_product_compare', 'enable_product_compare', false, Mapper::BOOL)
            ->add('max_comparable_products', 'max_comparable_products', 3, Mapper::INT)
            ->add('comparable_attributes', 'comparable_attributes', '')
            ->add('enable_recently_viewed_products', 'enable_recently_viewed_products', false, Mapper::BOOL)
            ->add('max_recently_viewed_products', 'max_recently_viewed_products', 5, Mapper::INT)
            ->add('tag_new_in_text', 'tag_new_in_text', '', Mapper::STRING)
            ->add('tag_new_in_expiration_days', 'tag_new_in_expiration_days', '', Mapper::STRING)
            ->withSourceRoot('catalog/review')
            ->add('active', 'rating', false, Mapper::BOOL)
            ->add('allow_guest', 'rating_guest', false, Mapper::BOOL)
            ->withSourceRoot('catalog/productalert')
            ->withDestinationRoot('storefrontConfig/catalog/products/options')
            ->add('enable_expand', 'enable_expand', false, Mapper::BOOL)
            ->add('expand_limit_options', 'expand_limit_options', 15, Mapper::INT)
            ->add('visible_height', 'visible_height', '')
            ->withSourceRoot('refilo_catalog/categories')
            ->withDestinationRoot('storefrontConfig/catalog/categories')
            ->add('show_filter_count', 'show_filter_count', false, Mapper::BOOL)
            ->withSourceRoot('catalog/magento_targetrule')
            ->withDestinationRoot('storefrontConfig/catalog/products/targetrule')
            ->add('related_position_limit', 'related/limit', 10, Mapper::INT)
            ->add('crosssell_position_limit', 'crosssell/limit', 10, Mapper::INT)
            ->add('upsell_position_limit', 'upsell/limit', 10, Mapper::INT)
            ->add('related_rotation_mode', 'related/rotation_mode', 'none', Mapper::STRING)
            ->add('crosssell_rotation_mode', 'crosssell/rotation_mode', 'none', Mapper::STRING)
            ->add('upsell_rotation_mode', 'upsell/rotation_mode', 'none', Mapper::STRING)
            ->resetDestinationRoot()
            ->resetSourceRoot();
    }

    /**
     * @param DataObject $configurations
     * @param StoreInterface|null $store
     * @return array
     * @throws NoSuchEntityException
     */
    protected function prepareData(DataObject $configurations, StoreInterface $store = null): array
    {
        $data = $configurations->toArray();
        $data['website'] = $store ? $store->getWebsite() : null;

        if (isset($data['refilo_general']['refilo_zendesk']['zendesk_departments'])) {
            $data['refilo_general']['refilo_zendesk']['zendesk_departments'] =
                $this->getListConfig($data['refilo_general']['refilo_zendesk']['zendesk_departments']);
        }

        if (isset($data['refilo_catalog']['categories']['pagination_mapping'])) {
            $paginationData = $this->getListConfig($data['refilo_catalog']['categories']['pagination_mapping']);
            if (isset($paginationData[0]['productnumber'])) {
                $paginationData[0]['productnumber'] = intval($paginationData[0]['productnumber']);
            }
            if (isset($paginationData[0]['categoryids'])) {
                $paginationData[0]['categoryids'] = explode(',', $paginationData[0]['categoryids']);
            }
            $data['refilo_catalog']['categories']['pagination_mapping'] = $paginationData;
        }

        if (isset($data['newsletter_popup']['general']['disabled_paths'])) {
            $data['newsletter_popup']['general']['disabled_paths'] =
                $this->getListConfig($data['newsletter_popup']['general']['disabled_paths']);
        }

        if (isset($data['newsletter_popup']['fields']['gender_list'])) {
            $data['newsletter_popup']['fields']['gender_list'] =
                $this->getListConfig($data['newsletter_popup']['fields']['gender_list']);
        }

        if (isset($data['newsletter_popup']['fields']['collections_list'])) {
            $data['newsletter_popup']['fields']['collections_list'] =
                $this->getListConfig($data['newsletter_popup']['fields']['collections_list']);
        }

        if (isset($data['maintenance_section']['general']['bg_image_mobile'])) {
            $data['maintenance_section']['general']['bg_image_mobile'] =
                "/filoblu/maintenance/{$data['maintenance_section']['general']['bg_image_mobile']}";
        }

        if (isset($data['maintenance_section']['general']['bg_image'])) {
            $data['maintenance_section']['general']['bg_image'] =
                "/filoblu/maintenance/{$data['maintenance_section']['general']['bg_image']}";
        }

        if (isset($data['design']['head']['shortcut_icon'])) {
            $data['design']['head']['shortcut_icon'] =
                "/favicon/{$data['design']['head']['shortcut_icon']}";
        }

        if (isset($data['refilo_marketing']['richsnippet_organization']['logo'])) {
            $data['refilo_marketing']['richsnippet_organization']['logo'] =
                "/richsnippet/{$data['refilo_marketing']['richsnippet_organization']['logo']}";
        }

        if (isset($data['refilo_marketing']['refilo_seo']['serp_thumbnail'])) {
            $data['refilo_marketing']['refilo_seo']['serp_thumbnail'] =
                "/filoblu/seo/{$data['refilo_marketing']['refilo_seo']['serp_thumbnail']}";
        }

        if ($configurations->getDataByPath('web/secure/use_in_frontend')) {
            $data['filoblu_url_to_use_in_frontend'] = $configurations->getDataByPath('web/secure/base_media_url');
        } else {
            $data['filoblu_url_to_use_in_frontend'] = $configurations->getDataByPath('web/unsecure/base_media_url');
        }

        $data['all_countries'] = [];
        $allCountry = $configurations->getDataByPath('general/country/allow');
        if ($allCountry) {
            $data['all_countries'] = explode(',', $allCountry);
        }

        $data['optional_zip_countries'] = [];
        $optionalZipCountries = $configurations->getDataByPath('general/country/optional_zip_countries');
        if ($optionalZipCountries) {
            $data['optional_zip_countries'] =explode(',', $optionalZipCountries);
        }

        $data['shipping_countries'] = [];
        $shippingCountries = $configurations->getDataByPath('refilo_geoip/country/allow_shipping');
        if ($shippingCountries) {
            $data['shipping_countries'] = explode(',', $shippingCountries);
        }

        if (!$configurations->getDataByPath('refilo_geoip/country/enabled_different_shipping_country')) {
            $data['shipping_countries'] = $data['all_countries'];
        }

        $data['country_url'] = [];
        if (isset($data['refilo_geoip']['country_url']['url_mapping'])) {
            $data['country_url'] = $this->prepareCountryUrlData($data['refilo_geoip']['country_url']['url_mapping']);
        }

        $data['security_csp_report_to'] = '';
        $data['security_csp_report_group'] = '';
        if (isset($data['refilo_security']['csp']['report_enabled']) && $data['refilo_security']['csp']['report_enabled'] == 1
        && isset($data['refilo_security']['csp']['report_uri']) && $data['refilo_security']['csp']['report_uri'] != '') {
            $reportToData = [
                'group' => 'report-endpoint',
                'max_age' => 10886400,
                'endpoints' => [
                    ['url' => $data['refilo_security']['csp']['report_uri']]
                ]
            ];
            $data['security_csp_report_to'] = $this->serializer->serialize($reportToData);
            $data['security_csp_report_group'] = 'report-endpoint';
        }

        $data['security_csp_rules'] = [];
        if (isset($data['refilo_security']['csp']['rules'])) {
            $rules = $this->serializer->unserialize($data['refilo_security']['csp']['rules']);
            if (!empty($rules)) {
                //remove magento unique keys
                $rules = array_values($rules);
                //swap "rule" index with "id" index and cast value to boolean
                $rules = array_map(function ($array_element) {
                    return ['id' => $array_element['rule'], 'enabled' => (bool) $array_element['enabled']];
                }, $rules);
                $data['security_csp_rules'] = $rules;
            }
        }

        foreach (['related', 'crosssell','upsell'] as $relationType) {
            $mode = (int)$configurations->getDataByPath("catalog/magento_targetrule/{$relationType}_rotation_mode");
            $translatedMode = 'shuffle';

            if ($mode === 1) {
                $translatedMode = 'none';
            }

            $data['catalog']['magento_targetrule']["{$relationType}_rotation_mode"] = $translatedMode;
        }

        if ($configurations->getDataByPath('refilo_catalog/categories/price_filterable_steps')) {
            $rules = $this->serializer->unserialize($configurations->getDataByPath('refilo_catalog/categories/price_filterable_steps'));
            $output = [];
            foreach ($rules as $rule) {
                $output[] = (float) $rule['from'];
                $output[] = (float) $rule['to'];
            }
            $data['refilo_catalog']['categories']['price_filterable_steps'] = array_values(array_unique($output, SORT_NUMERIC));
        }

        if (!$this->moduleManager->isEnabled('FiloBlu_Storelocator')) {
            $data['filoblu_storelocator_section']['general']['enabled'] = '0';
        }

        return $data;
    }

    /**
     * @param Mapper $mapper
     * @return Mapper
     */
    protected function setMappings(Mapper $mapper)
    {
        $this->addGeneral($mapper);
        $this->addCatalog($mapper);
        $this->addNotification($mapper);
        $this->addGeoIp($mapper);
        $this->addSearch($mapper);
        $this->addMarketing($mapper);
        $this->addStoreLocator($mapper);
        $this->addContent($mapper);
        $this->addMaintenance($mapper);
        $this->addSales($mapper);
        $this->addSocial($mapper);
        $this->addNewsLetter($mapper);
        $this->addCustomer($mapper);
        $this->addRecaptcha($mapper);
        $this->addSecurity($mapper);
        $this->addCustomerCare($mapper);
        return $mapper;
    }

    /**
     * @param Mapper $mapper
     * @return Mapper
     */
    protected function addSocial(Mapper $mapper)
    {
        return $mapper
            ->add('refilo_social/login/facebook_app_id', 'storefrontConfig/social/login/facebook_app_id', '')
            ->add('refilo_social/login/google_client_id', 'storefrontConfig/social/login/google_client_id', '')
            ->add('refilo_social/login/apple_client_id', 'storefrontConfig/social/login/apple_client_id', '');
    }

    /**
     * @param Mapper $mapper
     * @return Mapper
     */

    protected function addCustomerCare(Mapper $mapper): Mapper
    {
        return $mapper
            ->withDestinationRoot('storefrontConfig/general/amazon_connect_chat')
            ->add('refilo_customer_care/amazon_connect_chat/enabled', 'enabled', false, Mapper::BOOL)
            ->add('refilo_customer_care/amazon_connect_chat/widget_id', 'widget_id', '', Mapper::STRING)
            ->add('refilo_customer_care/amazon_connect_chat/script_url', 'script_url', '', Mapper::STRING)
            ->add('refilo_customer_care/amazon_connect_chat/script_id', 'script_id', '', Mapper::STRING)
            ->add('refilo_customer_care/amazon_connect_chat/snippet_id', 'snippet_id', '', Mapper::STRING)
            ->withDestinationRoot('storefrontConfig/general/amazon_connect_chat_custom')
            ->add('refilo_customer_care/amazon_connect_chat_custom/enabled', 'enabled', false, Mapper::BOOL);
    }

    /**
     * @param Mapper $mapper
     */
    protected function addGeneral(Mapper $mapper)
    {
        $mapper
            ->withDestinationRoot('storefrontConfig/general')
            ->add('design/head/default_title', 'site_name', '')
            ->add('design/footer/copyright', 'copyright', '')
            ->add('refilo_general/discalimers_topbar/top_strip', 'top_strip', '')
            ->withSourceRoot('refilo_general/discalimers_topbar')
            ->withDestinationRoot('storefrontConfig/general/disclaimers')
            ->add('terms_conditions', 'terms_and_conditions', '')
            ->add('marketing_disclaimer', 'marketing', '')
            ->add('profiling_disclaimer', 'profiling', '')
            ->add('privacy_disclaimer', 'privacy_policy', '')
            ->add('cookie_disclaimer', 'cookie_policy', '')
            ->withSourceRoot('refilo_general/discalimers_addresses')
            ->withDestinationRoot('storefrontConfig/general/disclaimers/address')
            ->add('street_additional_label', 'street_additional_label', '')
            ->add('company_additional_label', 'company_additional_label', '')
            ->withSourceRoot('refilo_general/discalimers_checkout')
            ->withDestinationRoot('storefrontConfig/general/disclaimers/checkout')
            ->add('rassurance_info', 'rassurance_info', '')
            ->add('custom_duties_disclaimer', 'custom_duties_disclaimer', '')
            ->withSourceRoot('refilo_general/floating_actions')
            ->withDestinationRoot('storefrontConfig/general/floating_actions')
            ->add('position', 'position', '')
            ->add('top', 'top', '')
            ->add('single_widget', 'single_widget', false, Mapper::BOOL)
            ->withSourceRoot('refilo_general/discalimers_contacts')
            ->withDestinationRoot('storefrontConfig/general/disclaimers')
            ->add('contacts_form', 'contacts_form', '')
            ->add('work_with_us_form', 'work_with_us_form', '')
            ->withSourceRoot('refilo_general/discalimers_oosn')
            ->withDestinationRoot('storefrontConfig/general/disclaimers')
            ->add('out_of_stock_notification_form', 'out_of_stock_notification', '')
            ->withSourceRoot('refilo_general/address_autocomplete')
            ->withDestinationRoot('storefrontConfig/general/address_autocomplete')
            ->add('enable_address_autocomplete', 'enabled', false, Mapper::BOOL)
            ->add('autocomplete_api_key', 'api_key', '')
            ->withSourceRoot('refilo_general/refilo_zendesk')
            ->withDestinationRoot('storefrontConfig/general/zendesk')
            ->add('zendesk_script_src', 'script_src', '')
            ->add('zendesk_departments', 'departments', [])
            ->add('zendesk_preselected_department', 'preselected_department', '')
            ->withSourceRoot('refilo_general/refilo_whatsapp')
            ->withDestinationRoot('storefrontConfig/general/whatsapp')
            ->add('whatsapp_number', 'number', '')
            ->add('whatsapp_prefilled', 'prefilled', '')
            ->withSourceRoot('general/restriction')
            ->withDestinationRoot('storefrontConfig/general/restriction')
            ->add('is_active', 'is_active', false, Mapper::BOOL)
            ->add('mode', 'mode', 0, Mapper::INT)
            ->add('http_redirect', 'startup_page', 0, Mapper::INT)
            ->add('cms_page', 'landing_page', '')
            ->add('http_status', 'http_response', 0, Mapper::INT)
            ->add('allowed_path', 'allowed_path', '')
            ->resetSourceRoot()
            ->resetDestinationRoot()
            ->add('general/locale', 'storefrontConfig/general/locale', [])
            ->add('general/locale/code', 'storefrontConfig/general/locale/name', '')
            ->add('website/code', 'storefrontConfig/general/marketplace', self::DEFAULT)
            ->add('website/name', 'storefrontConfig/general/marketplace_name', self::DEFAULT)
            ->add('currency/options/default', 'storefrontConfig/general/default_currency', '')
            ->add('general/country/default', 'storefrontConfig/general/default_country', '')
            ->add('filoblu_url_to_use_in_frontend', 'storefrontConfig/general/media_base_url', '')
            ->add('all_countries', 'storefrontConfig/general/all_countries')
            ->add('optional_zip_countries', 'storefrontConfig/general/optional_zip_countries')
            ->add('shipping_countries', 'storefrontConfig/general/shipping_countries')
            ->add('country_url', 'storefrontConfig/general/country_url');
    }

    /**
     * Process StoreFront Notifications
     *
     * @param Mapper $mapper
     * @return Mapper
     */
    protected function addNotification(Mapper $mapper)
    {
        return $mapper
            ->add('refilo_notifications/general/enable_notifications', 'storefrontConfig/notification/enabled', false, Mapper::BOOL);
    }

    /**
     * @param Mapper $mapper
     * @return Mapper
     */
    protected function addGeoIp(Mapper $mapper)
    {
        return $mapper
            ->withSourceRoot('refilo_geoip/geoip_config')
            ->withDestinationRoot('storefrontConfig/geoip')
            ->add('geoip_enabled', 'enabled', true, Mapper::BOOL)
            ->add('enable_popup', 'popup', true, Mapper::BOOL)
            ->add('geoip_cookie_name', 'geoinfo_cookie_name', '')
            ->add('geoip_cookie_age', 'geoinfo_cookie_age', 86400000, Mapper::INT)
            ->add('misfits', 'misfits', true, Mapper::BOOL)
            ->add('misfits_cookie_name', 'misfits_cookie_name', '')
            ->add('misfits_cookie_age', 'misfits_cookie_age', 2592000, Mapper::INT)
            ->add('root_redirect_code', 'root_redirect_code', 301, Mapper::INT)
            ->resetSourceRoot()
            ->resetDestinationRoot();
    }

    /**
     * Process StoreFront Search
     * @param Mapper $mapper
     * @return Mapper
     */
    protected function addSearch(Mapper $mapper)
    {
        return $mapper
            ->withSourceRoot('catalog/search')
            ->withDestinationRoot('storefrontConfig/search')
            ->add('search_recommendations_enabled', 'recommendations', true, Mapper::BOOL)
            ->add('search_recommendations_count', 'recommendations_limit', 5, Mapper::INT)
            ->add('search_suggestion_enabled', 'search_suggestion_enabled', true, Mapper::BOOL)
            ->add('search_suggestion_count', 'search_suggestion_count', 5, Mapper::INT)
            ->withSourceRoot('refilo_search/recommendations')
            ->withDestinationRoot('storefrontConfig/search')
            ->add('suggestion_enabled', 'recommendations_suggestion_enabled', false, Mapper::BOOL)
            ->withSourceRoot('refilo_search/external_service')
            ->withDestinationRoot('storefrontConfig/search/externalService')
            ->add('enabled', 'enabled', false, Mapper::BOOL)
            ->add('adapter', 'adapter', '', Mapper::STRING)
            ->add('api_url', 'api_url', '', Mapper::STRING)
            ->resetSourceRoot()
            ->resetDestinationRoot();
    }

    /**
     * Process StoreFront GTagManager
     *
     * @param Mapper $mapper
     * @return Mapper
     */
    protected function addMarketing(Mapper $mapper)
    {
        return $mapper
            ->withSourceRoot('refilo_marketing/google_tagmanager')
            ->withDestinationRoot('storefrontConfig/google_tag_manager')
            ->add('enabled', 'enabled', false, Mapper::BOOL)
            ->add('code', 'code', '')
            ->add('auth', 'auth', '')
            ->add('preview', 'preview', '')
            ->add('file_url', 'file_url', '')
            ->withSourceRoot('refilo_marketing/builtin_search_metrics')
            ->withDestinationRoot('storefrontConfig/builtin_search_metrics')
            ->add('enabled', 'enabled', false, Mapper::BOOL)
            ->withSourceRoot('refilo_marketing/richsnippet_organization')
            ->withDestinationRoot('storefrontConfig/rich_snippet/organization')
            ->add('logo', 'logo', '')
            ->withSourceRoot('refilo_marketing/richsnippet_product')
            ->withDestinationRoot('storefrontConfig/rich_snippet/product')
            ->add('brand', 'brand', '')
            ->withSourceRoot('refilo_marketing/refilo_seo')
            ->withDestinationRoot('storefrontConfig/seo')
            ->add('serp_thumbnail', 'serp_thumbnail', '')
            ->resetSourceRoot()
            ->resetDestinationRoot();
    }

    /**
     * Process StoreFront StoreLocator
     *
     * @param Mapper $mapper
     * @return Mapper
     */
    protected function addStoreLocator(Mapper $mapper)
    {
        return $mapper
            ->withSourceRoot('filoblu_storelocator_section/general')
            ->withDestinationRoot('storefrontConfig/storelocator')
            ->add('enabled', 'enabled', true, Mapper::BOOL)
            ->add('gmaps_api_key', 'key', '')
            ->add('shop_details', 'details/enabled', false, Mapper::BOOL)
            ->withSourceRoot('filoblu_storelocator_section/search')
            ->withDestinationRoot('storefrontConfig/storelocator/autocomplete')
            ->add('gmaps_search_autocomplete_enabled', 'enabled', false, Mapper::BOOL)
            ->add('gmaps_search_autocomplete_type', 'type', '')
            ->add('gmaps_search_autocomplete_zoom', 'zoom', 11, Mapper::INT)
            ->withDestinationRoot('storefrontConfig/storelocator/tags')
            ->add('gmaps_search_tag_enabled', 'enabled', true, Mapper::BOOL)
            ->withSourceRoot('filoblu_storelocator_section/map_options')
            ->withDestinationRoot('storefrontConfig/storelocator/map')
            ->add('gmaps_default_center', 'default_center', [])
            ->add('gmaps_default_zoom', 'default_zoom', 5, Mapper::INT)
            ->add('gmaps_min_zoom', 'min_zoom', 20, Mapper::INT)
            ->add('gmaps_max_zoom', 'max_zoom', 20, Mapper::INT)
            ->add('gmaps_type', 'type', '')
            ->add('gmaps_style', 'style', '')
            ->add('gmaps_ui_zoomControl_enabled', 'controls/zoom', true, Mapper::BOOL)
            ->add('gmaps_ui_mapTypeControl_enabled', 'controls/map_type', true, Mapper::BOOL)
            ->add('gmaps_ui_streetViewControl_enabled', 'controls/street_view', true, Mapper::BOOL)
            ->add('gmaps_ui_rotateControl_enabled', 'controls/rotate', true, Mapper::BOOL)
            ->add('gmaps_ui_scaleControl_enabled', 'controls/scale', true, Mapper::BOOL)
            ->add('gmaps_ui_fullscreenControl_enabled', 'controls/fullscreen', true, Mapper::BOOL)
            ->withSourceRoot('filoblu_storelocator_section/geolocation')
            ->withDestinationRoot('storefrontConfig/storelocator/geolocation')
            ->add('gmaps_geolocation_enabled', 'enabled', true, Mapper::BOOL)
            ->add('gmaps_geolocation_zoom', 'zoom', 12, Mapper::INT)
            ->add('gmaps_geolocation_distance_enabled', 'distance', true, Mapper::BOOL)
            ->add('gmaps_geolocation_direction', 'directions', true, Mapper::BOOL)
            ->add('gmaps_geolocation_travelmode', 'travel_mode', '')
            ->withSourceRoot('filoblu_storelocator_section/markers')
            ->withDestinationRoot('storefrontConfig/storelocator/marker')
            ->add('gmaps_markers_marker_image', 'image', '')
            ->add('gmaps_markers_cluster_image', 'cluster_image', '')
            ->withSourceRoot('filoblu_storelocator_section/product_in_store')
            ->withDestinationRoot('storefrontConfig/storelocator/product_in_store')
            ->add('enable_product_in_store', 'enable_product_in_store', false, Mapper::BOOL)
            ->resetSourceRoot()
            ->resetDestinationRoot();
    }

    /**
     * @param Mapper $mapper
     * @return Mapper
     */
    protected function addContent(Mapper $mapper)
    {
        return $mapper
            ->withSourceRoot('refilo_content/general')
            ->withDestinationRoot('storefrontConfig/content/pages')
            ->add('not_seo_friendly_urls', 'not_seo_friendly_urls', '')
            ->withSourceRoot('design/head')
            ->withDestinationRoot('storefrontConfig/content/html_head')
            ->add('default_title', 'default_title', '')
            ->add('demonotice', 'demonotice', false, Mapper::BOOL)
            ->add('default_keywords', 'meta_keywords', '')
            ->add('includes', 'include_script', '')
            ->add('title_prefix', 'title_prefix', '')
            ->add('title_suffix', 'title_suffix', '')
            ->add('default_description', 'meta_description', '')
            ->add('shortcut_icon', 'favicon', '')
            ->withSourceRoot('design/footer')
            ->withDestinationRoot('storefrontConfig/content/footer')
            ->add('absolute_footer', 'misc_html', '')
            ->withSourceRoot('design/search_engine_robots')
            ->withDestinationRoot('storefrontConfig/content/search_engine_robots')
            ->add('default_robots', 'default_robots', '')
            ->add('custom_instructions', 'custom_instructions', '')
            ->resetSourceRoot()
            ->resetDestinationRoot();
    }

    /**
     * @param Mapper $mapper
     * @return Mapper
     */
    protected function addMaintenance(Mapper $mapper)
    {
        return $mapper
            ->withSourceRoot('maintenance_section/general')
            ->withDestinationRoot('storefrontConfig/maintenance')
            ->add('enabled', 'enabled', false, Mapper::BOOL)
            ->add('allowed_urls', 'allowed_urls', '')
            ->add('allowed_ips', 'allowed_ips', '')
            ->add('page_title', 'page_title', '')
            ->add('bg_image', 'bg_image', '')
            ->add('front_text', 'front_text', '')
            ->add('bg_image_mobile', 'bg_image_mobile', '')
            ->resetDestinationRoot()
            ->resetSourceRoot();
    }

    /**
     * @param Mapper $mapper
     * @return Mapper
     */
    protected function addSales(Mapper $mapper)
    {
        return $mapper
            ->withSourceRoot('refilo_sales')
            ->withDestinationRoot('storefrontConfig/sales')
            ->add('gift_message/enabled', 'gift_message/enabled', true, Mapper::BOOL)
            ->add('gift_wrap/enabled', 'gift_wrap/enabled', true, Mapper::BOOL)
            ->add('coupon/disabled', 'coupon/disabled', false, Mapper::BOOL)
            ->withSourceRoot('giftcard')
            ->add('general/is_redeemable', 'gift_cards/enabled', false, Mapper::BOOL)
            ->withSourceRoot('carriers/pickupinstore')
            ->withDestinationRoot('storefrontConfig/sales/checkout')
            ->add('active', 'pickup_in_store/enabled', false, Mapper::BOOL)
            ->withSourceRoot('tax/cart_display')
            ->withDestinationRoot('storefrontConfig/sales/tax')
            ->add('full_summary', 'display_summary', true, Mapper::BOOL)
            ->add('zero_tax', 'display_zero', false, Mapper::BOOL)
            ->withSourceRoot('refilo_sales')
            ->withDestinationRoot('storefrontConfig/sales')
            ->add('checkout/disable_terms_and_conditions', 'checkout/disable_terms_and_conditions', false, Mapper::BOOL)
            ->withSourceRoot('sales')
            ->withDestinationRoot('storefrontConfig/sales')
            ->add('magento_rma/enabled', 'rma/enabled', true, Mapper::BOOL)
            ->withDestinationRoot('storefrontConfig/sales/checkout/invoice')
            ->withSourceRoot('refilo_sales/checkout')
            ->add('invoice_external_vat_validation_enabled', 'external_vat_validation_enabled', false, Mapper::BOOL)
            ->resetDestinationRoot()
            ->resetSourceRoot();
    }

    /**
     * @param Mapper $mapper
     * @return Mapper
     */
    protected function addNewsLetter(Mapper $mapper)
    {
        return $mapper
            ->withSourceRoot('newsletter_popup/general')
            ->withDestinationRoot('storefrontConfig/newsletter_popup')
            ->add('enable_popup', 'enabled', true, Mapper::BOOL)
            ->add('enable_auto_open', 'auto_open', true, Mapper::BOOL)
            ->add('close_timeout', 'close_timeout', 3000, Mapper::INT)
            ->add('open_timeout', 'open_timeout', 3000, Mapper::INT)
            ->add('cookie_name', 'cookie_name', '')
            ->add('cookie_lifetime', 'cookie_lifetime', 2592000, Mapper::INT)
            ->add('disabled_paths', 'disabled_paths', [])
            ->add('visited_before_open', 'visited_before_open', '')
            ->withSourceRoot('newsletter_popup/fields')
            ->withDestinationRoot('storefrontConfig/newsletter_popup/fields')
            ->add('firstname_enabled', 'firstname/enabled', true, Mapper::BOOL)
            ->add('firstname_required', 'firstname/required', false, Mapper::BOOL)
            ->add('lastname_enabled', 'lastname/enabled', true, Mapper::BOOL)
            ->add('lastaname_required', 'lastname/required', false, Mapper::BOOL)
            ->add('lastname_enabled', 'lastname/enabled', true, Mapper::BOOL)
            ->add('lastname_required', 'lastname/required', false, Mapper::BOOL)
            ->add('dob_enabled', 'dob/enabled', true, Mapper::BOOL)
            ->add('dob_required', 'dob/required', false, Mapper::BOOL)
            ->add('gender_enabled', 'gender/enabled', true, Mapper::BOOL)
            ->add('gender_required', 'gender/required', false, Mapper::BOOL)
            ->add('gender_list', 'gender/list', [])
            ->add('country_enabled', 'country/enabled', true, Mapper::BOOL)
            ->add('country_required', 'country/required', false, Mapper::BOOL)
            ->add('collections_enabled', 'collections/enabled', true, Mapper::BOOL)
            ->add('collections_required', 'collections/required', false, Mapper::BOOL)
            ->add('collections_list', 'collections/list', [])
            ->add('phone_enabled', 'phone/enabled', true, Mapper::BOOL)
            ->add('phone_required', 'phone/required', false, Mapper::BOOL)
            ->resetSourceRoot()
            ->resetDestinationRoot();
    }

    /**
     * Process StoreFront Customer Configs
     *
     * @param Mapper $mapper
     * @return Mapper
     */
    protected function addCustomer(Mapper $mapper)
    {
        return $mapper
            ->withSourceRoot('refilo_customer/address_validation')
            ->withDestinationRoot('storefrontConfig/customer/address_validation')
            ->add('firstname_lastname_sum', 'firstname_lastname_sum', 35, Mapper::INT)
            ->add('firstname_length', 'firstname_length', 32, Mapper::INT)
            ->add('lastname_length', 'lastname_length', 32, Mapper::INT)
            ->add('street_length', 'street_length', 120, Mapper::INT)
            ->add('street_fields_number', 'street_fields_number', 1, Mapper::INT)
            ->add('postcode_length', 'postcode_length', 9, Mapper::INT)
            ->add('city_length', 'city_length', 30, Mapper::INT)
            ->add('region_length', 'region_length', 30, Mapper::INT)
            ->withSourceRoot('magento_reward/general')
            ->withDestinationRoot('storefrontConfig/customer/reward_points')
            ->add('is_enabled_on_front', 'is_enabled', false, Mapper::BOOL)
            ->withSourceRoot('refilo_customer/address_fields')
            ->withDestinationRoot('storefrontConfig/customer/address/fields')
            ->add('careof_enable', 'care_of', false, Mapper::BOOL)
            ->resetSourceRoot()
            ->resetDestinationRoot();
    }

    /**
     * Process StoreFront Recaptcha Configs
     *
     * @param Mapper $mapper
     * @return Mapper
     */
    protected function addRecaptcha(Mapper $mapper)
    {
        return $mapper
            ->withSourceRoot('refilo_google_recaptcha/general')
            ->withDestinationRoot('storefrontConfig/google_recaptcha')
            ->add('enabled', 'enabled', false, Mapper::BOOL)
            ->add('site_key', 'site_key', '')
            ->add('secret_key', 'secret_key', '')
            ->add('api_enabled', 'api_enabled', '')
            ->add('bypass_ips', 'bypass_ips', '')
            ->add('score', 'score', 0.5, Mapper::FLOAT)
            ->resetSourceRoot()
            ->resetDestinationRoot();
    }

    protected function addSecurity(Mapper $mapper)
    {
        return $mapper
            ->withSourceRoot('refilo_security/csp')
            ->withDestinationRoot('storefrontConfig/security/csp')
            ->add('enabled', 'enabled', false, Mapper::BOOL)
            ->add('report_only', 'reportOnly', true, Mapper::BOOL)
            ->withDestinationRoot('storefrontConfig/security/csp/report')
            ->add('report_enabled', 'enabled', false, Mapper::BOOL)
            ->add('report_uri', 'reportUri', '')
            ->withDestinationRoot('storefrontConfig/security/csp/rulesCustom')
            ->add('base_uri', 'base-uri', '')
            ->add('default_src', 'default-src', '')
            ->add('child_src', 'child-src', '')
            ->add('connect_src', 'connect-src', '')
            ->add('manifest_src', 'manifest-src', '')
            ->add('media_src', 'media-src', '')
            ->add('object_src', 'object-src', '')
            ->add('style_src', 'style-src', '')
            ->add('script_src', 'script-src', '')
            ->add('img_src', 'img-src', '')
            ->add('frame_src', 'frame-src', '')
            ->add('frame_ancestors', 'frame-ancestors', '')
            ->add('form_action', 'form-action', '')
            ->add('font_src', 'font-src', '')
            ->resetSourceRoot()
            ->withDestinationRoot('storefrontConfig/security/csp')
            ->add('security_csp_rules', 'rules', '')
            ->withDestinationRoot('storefrontConfig/security/csp/report/reportTo')
            ->add('security_csp_report_to', 'configData', '')
            ->add('security_csp_report_group', 'code', '')
            ->resetDestinationRoot();
    }
}
