// Copyright (c) Pickware GmbH. All rights reserved.
// This file is part of software that is released under a proprietary license.
// You must not copy, modify, distribute, make publicly available, or execute
// its contents or parts thereof without express permission by the copyright
// holder, unless otherwise permitted by law.

// {namespace name=backend/viison_dhl_config/config}
Ext.define('Shopware.apps.ViisonDHLConfig.controller.Main', {

    extend: 'Shopware.apps.ViisonShippingCommonConfig.controller.Main',

    refs: [
        { ref: 'window', selector: 'viisondhlconfig-window' },
        { ref: 'panel', selector: 'viisondhlconfig-panel' },
    ],

    dispatchServiceProviderConfigModelClass: 'Shopware.apps.ViisonDHLConfig.model.DHL',

    /**
     * Stores
     * @default null
     * @object
     */
    configStore: null,

    /**
     * Supported countries store
     * @default null
     * @object
     */
    supportedSenderCountriesStore: null,

    /**
     * Contains all snippets for the view component.
     */
    snippets: {
        notifications: {
            saveConfigurationSuccess: {
                title: '{s name="main/notifications/save_configuration_success/title"}{/s}',
                message: '{s name="main/notifications/save_configuration_success/message"}{/s}',
            },
            saveConfigurationError: {
                title: '{s name="main/notifications/save_configuration_error/title"}{/s}',
                message: '{s name="main/notifications/save_configuration_error/message"}{/s}',
            },
            saveConfigurationValidationError: {
                title: '{s name="main/notifications/save_configuration_validation_error/title"}{/s}',
                message: '{s name="main/notifications/save_configuration_validation_error/message"}{/s}',
            },
            loadAllConfigurationsError: {
                title: '{s name="main/notifications/load_all_configurations_error/title"}{/s}',
                message: '{s name="main/notifications/load_all_configurations_error/message"}{/s}',
            },
            destroyConfigurationSuccess: {
                title: '{s name="main/notifications/destroy_configuration_success/title"}{/s}',
                message: '{s name="main/notifications/destroy_configuration_success/message"}{/s}',
            },
            destroyConfigurationError: {
                title: '{s name="main/notifications/destroy_configuration_error/title"}{/s}',
                message: '{s name="main/notifications/destroy_configuration_error/message"}{/s}',
            },
            growlMessage: '{s name="main/notifications/growlMessage"}{/s}',
        },
    },

    constructor: function () {
        // Get/Create config store
        this.configStore = (Ext.getStore('viison-dhl-config-store')
                            || Ext.create('Shopware.apps.ViisonDHLConfig.store.DHL')).load();

        // Get/Create countries store and load it
        this.supportedSenderCountriesStore = (
            Ext.getStore('viison-dhl-config-suppoted-countries-store')
            || Ext.create('Shopware.apps.ViisonDHLConfig.store.SupportedCountries')
        ).load();

        this.callParent(arguments);
    },

    /**
     * @Override
     */
    init: function () {
        // Register listeners
        this.control({
            'viison-shipping-common-config-window combobox[origName=countryiso]': {
                select: this.onChangeSupportedCountry,
            },
        });

        this.callParent(arguments);
    },

    /**
     * @Override
     * Send to the panel data from the controller
     *
     * Note: The data will always be transferred to the View in a 'additionalData' object
     *
     * @return object
     */
    createAdditionalWindowData: function () {
        return {
            configStore: this.configStore,
            supportedSenderCountriesStore: this.supportedSenderCountriesStore,
        };
    },

    /**
     * On Change event listener for Country SelectBox, trigger hide/show field logic
     * @param field
     */
    onChangeSupportedCountry: function (field) {
        var form = this.getPanel().getForm();

        // Here we have the guaranty that the countries store is loaded
        // because the Combobox with the data is rendered
        this.toggleFieldsByCountry(form.getValues(), field.shopId, form, this.getPanel());
    },

    /**
     * Additional setup on form in onLoad panel phase state
     *
     * Note: This function is called from onLoad method in ShippingCommon
     *
     * @param object configDataByShopId Configuration data from Store in value[shopId][*] form
     * @param string shopId The ID of the given shop, (form fields are sorted via shopId)
     * @param object form The form containing all fields from all shops
     * @param object panel The panel containing all fields from all shops
     */
    additionalFormSetupOnLoad: function (configDataByShopId, shopId, form, panel) {
        if (!this.supportedSenderCountriesStore.getTotalCount()) {
            // Case data is not loaded, load data and continue with view load
            // This can happen by slow Internet connection
            this.supportedSenderCountriesStore.load({
                scope: this,
                callback: function (records, operation, success) {
                    if (success) {
                        this.toggleFieldsByCountry(configDataByShopId, shopId, form, panel);
                    }
                },
            });
        } else {
            // Data is loaded continue with view load
            this.toggleFieldsByCountry(configDataByShopId, shopId, form, panel);
        }
    },

    /**
     * Toggle fields by Country, this function will be called for every sub-shop configuration
     *
     * @param object configDataByShopId Configuration data from Store in value[shopId][*] form
     * @param string shopId The ID of the given shop, (form fields are sorted via shopId)
     * @param object form The form containing all fields from all shops
     *  @param object panel The panel containing all fields from all shops
     */
    toggleFieldsByCountry: function (configDataByShopId, shopId, form, panel) {
        if (!configDataByShopId || !shopId || !form) {
            throw new Error('[ERROR::DHL] Config data, shopId, form or panel is not defined in DHL config main controller.');
        }

        /** Function helpers */

        // Function currying (hard binding), bind 'this' to be the form for later use
        var findField = (form.findField).bind(form);
        var findValueFn = function (key) {
            return configDataByShopId[key];
        };
        var fastAccessFn = function (orderAccess, key) {
            return orderAccess('values[' + shopId + '][%s]'.replace(/%s/, key)) || null;
        };

        // ShippingCommon gives guaranty that the store is always landed when the View is ready
        var countriesStore = this.supportedSenderCountriesStore;
        var shopConfig = this.configStore.findRecord('shopId', shopId);

        // Get participant codes if defined for the selected country
        // The codes are defined inside the PluginInfo in the Backend
        var countryIso = fastAccessFn(findValueFn, 'countryiso');
        var codes = (countryIso) ? countriesStore.findRecord('countryiso', countryIso) : null;

        codes = (codes) ? codes.get('codes') : null;
        if (!codes) {
            // Because the model of the country will set the codes field by default to Array
            // This is the case if something unexpected happens, do nothing
            return;
        }

        // We suspend the update layout to speed up the toggle process
        Ext.suspendLayouts();

        // Get all partnerId and defaultShipmentWeight fields except Express fields (Express is International available)
        var fieldsToToggle = [];
        Object.keys(shopConfig.data).forEach(function (key) {
            if (key.indexOf('EXP') === -1 && (key.indexOf('partnerId') > -1 || key.indexOf('defaultShipmentWeight') > -1)) {
                fieldsToToggle.push(key);
            }
        });

        /** Toggle fields logic */

        var ekpField = fastAccessFn(findField, 'EKP');
        panel = panel || ekpField.up(); // Just in case so the panel is always loaded

        // Get specific fields that need to be toggled if express land is selected
        var ekpSeperator = panel.down('container[cls=viison-label-seperator-EKP]'); // The label can't be get via the form
        var dhlLoginSeperator = panel.down('container[cls=viison-label-seperator-dhl-login]');
        var usernameField = fastAccessFn(findField, 'username');
        var passwordField = fastAccessFn(findField, 'password');
        var verifyCredentialsBtn = panel.down('container[cls=viison-button-verify-credentials]'); // The btn container can't be get via the form

        if (!codes.length) {
            // Only EXP is supported for this kind of countries
            ekpSeperator.hide();
            ekpField.disable().hide();
            dhlLoginSeperator.hide();
            usernameField.disable().hide();
            passwordField.disable().hide();
            verifyCredentialsBtn.hide();
        } else {
            // Show the DHL specific fields
            ekpSeperator.show();
            ekpField.enable().show();
            dhlLoginSeperator.show();
            usernameField.enable().show();
            passwordField.enable().show();
            verifyCredentialsBtn.show();
        }

        var match;
        fieldsToToggle.forEach(function (field) {
            match = codes.filter(function (code) {
                return field.indexOf(code) > -1;
            });
            if (match && match.length) {
                fastAccessFn(findField, field).enable().show();
            } else {
                fastAccessFn(findField, field).disable().hide();
            }
        });

        Ext.resumeLayouts(true);
    },
});
