// 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.

/**
 * The main panel of the LabelConfirmWindow containing all form fields, which hold the shipping details
 * and settings of this record(order). Furthermore two buttons (cancel, confirm) are added.
 */
// {namespace name="backend/viison_dhl_order/order"}
Ext.define('Shopware.apps.ViisonDHLOrder.view.detail.LabelConfirm', {

    /**
     * Extend from the standard ExtJS 4.
     */
    extend: 'Shopware.apps.ViisonShippingCommonOrder.view.detail.LabelConfirm',

    /**
     * List of short aliases for class names. Most useful for defining xtypes for widgets.
     */
    alias: 'widget.order-viison-dhl-label-confirm-panel',

    /**
     * An optional extra CSS class that will be added to this component's Element.
     */
    cls: Ext.baseCSSPrefix + 'order-viison-dhl-label-confirm-panel',

    /**
     * The plugin specific prefix used for the custom order record entries
     */
    dispatchServiceProviderPrefix: 'ViisonDHL',
    dispatchServiceProviderName: 'DHL',

    /**
     * More plugin-specific properties required by the parent class
     */
    maxLength: null,

    /**
     * Constraints for DHL Services
     *
     * Structure:
     * {
     *   on: {
     *      enable - Products where the section's needs to be activated by selection
     *      disable - Products where the section's needs to be deactivated by selection
     *   },
     *   required - Products that require this fields,
     *   functionRule - Function that will be executed by this Product selection
     *   nameIdentifier - Matching Identifier
     * }
     */
    dhlServiceProductConstraints: null,

    /**
     * The property where the DHL packing station data from MOB will be stored.
     */
    dhlPackingStationStore: null,

    /**
     * Contains all snippets for the view component.
     */
    customSnippets: {
        tooltips: {
            personalHandoverHelp: '{s name="label_confirm/tooltips/personal_handover_help"}{/s}',
            preferredDayHelp: '{s name="label_confirm/tooltips/preferred_day_help"}{/s}',
            parcelOutletRoutingHelp: '{s name="label_confirm/tooltips/parcel_outlet_routing_help"}{/s}',
            preferredLocation: '{s name="label_confirm/tooltips/additional_information/preferred_location"}{/s}',
            preferredNeighbour: '{s name="label_confirm/tooltips/additional_information/preferred_neighbour"}{/s}',
            postalDeliveryDutyPaidHelp: '{s name="label_confirm/tooltips/postal_delivery_duty_paid_help"}{/s}',
            closestDroppointDeliveryHelp: '{s name="label_confirm/tooltips/closest_droppoint_delivery_help"}{/s}',
            signedForByRecipientHelp: '{s name="label_confirm/tooltips/signed_for_by_recipient"}{/s}',
        },
        settingsDetails: {
            labels: {
                product: '{s name="label_confirm/settings_details/labels/product"}{/s}',
                personalHandover: '{s name="label_confirm/settings_details/labels/personal_handover"}{/s}',
                minimumAge: '{s name="label_confirm/settings_details/labels/minimum_age"}{/s}',
                minimumAge16: '{s name="mapping_panel/items/visual_age_check/options/minimum_age_16 namespace=backend/viison_dhl_shipping/shipping"}{/s}',
                minimumAge18: '{s name="mapping_panel/items/visual_age_check/options/minimum_age_18 namespace=backend/viison_dhl_shipping/shipping"}{/s}',
                noMinimumAge: '{s name="mapping_panel/items/visual_age_check/options/no_minimum_age namespace=backend/viison_dhl_shipping/shipping"}{/s}',
                saturdayDelivery: '{s name="label_confirm/settings_details/labels/saturday_delivery"}{/s}',
                isInsuredValue: '{s name="label_confirm/settings_details/labels/is_insured_value"}{/s}',
                insuredValue: '{s name="label_confirm/settings_details/labels/insured_value"}{/s}',
                parcelOutletRouting: '{s name="label_confirm/settings_details/labels/parcel_outlet_routing"}{/s}',
                identCheck: '{s name="label_confirm/settings_details/labels/ident_check"}{/s}',
                postalDeliveryDutyPaid: '{s name="label_confirm/settings_details/labels/postal_delivery_duty_paid"}{/s}',
                closestDroppointDelivery: '{s name="label_confirm/settings_details/labels/closest_droppoint_delivery"}{/s}',
                signedForByRecipient: '{s name="label_confirm/settings_details/labels/signed_for_by_recipient"}{/s}',
            },
        },
        additionalInformation: {
            title: '{s name="label_confirm/additional_information/title"}{/s}',
            noNeighbourDelivery: '{s name="label_confirm/additional_information/no_neighbour_delivery/label"}{/s}',
            preferredDay: '{s name="label_confirm/additional_information/preferred_day/label"}{/s}',
            preferredLocation: '{s name="label_confirm/additional_information/preferred_location/label"}{/s}',
            preferredNeighbour: '{s name="label_confirm/additional_information/preferred_neighbour/label"}{/s}',
            emptyText: '{s name="label_confirm/additional_information/empty_text/label"}{/s}',
            emptyPreferredNeighbour: '{s name="label_confirm/additional_information/preferred_neighbour/empty"}{/s}',
            emptyPreferredLocation: '{s name="label_confirm/additional_information/preferred_location/empty"}{/s}',
            frankaturCombobox: {
                label: '{s name="label_confirm/additional_information/frankatur_combobox/label"}{/s}',
                help: '{s name="label_confirm/additional_information/frankatur_combobox/help"}{/s}',
            },
            incotermCombobox: {
                label: '{s name="label_confirm/additional_information/incoterm_combobox/label"}{/s}',
                help: '{s name="label_confirm/additional_information/incoterm_combobox/help"}{/s}',
            },
            addresseesCustomsReference: {
                label: '{s name="label_confirm/additional_information/addressees_customs_reference/label"}{/s}',
                help: '{s name="label_confirm/additional_information/addressees_customs_reference/help"}{/s}',
            },
            endorsementTypeCombobox: {
                label: '{s name="mapping_panel/items/endorsement_type_combobox/label namespace=backend/viison_dhl_shipping/shipping"}{/s}',
                help: '{s name="mapping_panel/items/endorsement_type_combobox/help namespace=backend/viison_dhl_shipping/shipping"}{/s}',
                options: {
                    notSpecified: '{s name="mapping_panel/items/endorsement_type_combobox/options/not_specified namespace=backend/viison_dhl_shipping/shipping"}{/s}',
                    immediate: '{s name="mapping_panel/items/endorsement_type_combobox/options/immediate namespace=backend/viison_dhl_shipping/shipping"}{/s}',
                    abandonment: '{s name="mapping_panel/items/endorsement_type_combobox/options/abandonment namespace=backend/viison_dhl_shipping/shipping"}{/s}',
                },
            },
        },
    },

    /**
     * @Override
     */
    initComponent: function () {
        this.dhlServiceProductConstraints = {
            settings: {
                disabledForCode: ['EXP'],
                supportsCashOnDelivery: ['V01PAK', 'V01PRIO', 'V53WPAK'],
                supportsPersonalHandover: ['V01PAK', 'V01PRIO'],
                supportsVisualAgeCheck: ['V01PAK', 'V01PRIO'],
                supportsIdentCheck: ['V01PAK'],
                supportsClosestDroppointDelivery: ['V53WPAK'],
                supportsPostalDeliveryDutyPaid: ['V53WPAK'],
                supportsSignedForByRecipient: ['V01PAK'],
            },
            express: {
                enabledForCode: ['EXP'],
                supportsSaturdayDelivery: ['N', '1'],
            },
        };

        // Use 'Ext.apply' so if a error by loading the constraints occurs,
        // the object still has the default values
        this.maxLength = Ext.apply({}, this.dimensionConstraints || {}, {
            firstName: undefined,
            lastName: undefined,
            companyName: undefined,
            companyDepartment: undefined,
            street: undefined, // No maximum length for street name and house number combined into a single string
            streetName: undefined,
            streetNumber: undefined,
            additionalAddressLine: undefined,
            zip: undefined,
            city: undefined,
            phoneNumber: undefined,
            email: undefined,
            weight: undefined,
            length: undefined,
            width: undefined,
            height: undefined,
            preferredNeighbour: undefined,
            preferredLocation: undefined,
        });

        // Get/Create the DHL packing station store
        this.dhlPackingStationStore = Ext.getStore('viisonDHLPackingStationStore') || Ext.create('Shopware.apps.ViisonDHLOrder.store.DHLPackingStation');

        this.incotermStore = Ext.getStore('viisonDHLIncotermStore') || Ext.create('Shopware.apps.ViisonDHLTermsOfTrade.store.Incoterm');
        this.incotermExpressStore = Ext.getStore('viisonDHLIncotermExpressStore') || Ext.create('Shopware.apps.ViisonDHLTermsOfTrade.store.IncotermExpress');
        this.frankaturStore = Ext.getStore('viisonDHLFrankaturStore') || Ext.create('Shopware.apps.ViisonDHLTermsOfTrade.store.Frankatur');

        this.callParent(arguments);
    },

    /**
     * Returns the items that this panel consists of.
     */
    getItems: function () {
        var me = this;
        var items;
        if (!me.isReturn) {
            // forward label
            items = [
                me.createDetailsContainer(),
                me.createPackagingContainer(),
                me.createSettingsDetails(),
            ].concat(me.createExtraContainers());
        } else {
            // return label
            items = [
                me.createDetailsContainer(),
                me.createWeightFieldForReturnLabelContainer(), // Contains weight field
            ];
        }

        var detailsForm = me.detailsContainer.getForm();
        detailsForm.findField('streetNumber').allowBlank = true;

        return items;
    },

    /**
     * Creates all label type form rows containing a label and at least one input field.
     *
     * @param labelWidth The width for all labels in this panel.
     * @param columnPadding
     * @return An array containing the created rows.
     */
    createSettingsFormRows: function (labelWidth, columnPadding) {
        var me = this;

        /**
         *  Section :: DHL Settings Options
         */
        me.personalHandover = Ext.create('Ext.form.field.Checkbox', {
            name: 'personalHandover',
            fieldLabel: me.customSnippets.settingsDetails.labels.personalHandover,
            helpText: me.customSnippets.tooltips.personalHandoverHelp,
            required: false,
            checked: false,
            uncheckedValue: false,
            inputValue: true,
        });

        me.minimumAge = Ext.create('Ext.form.field.ComboBox', {
            name: 'minimumAge',
            required: false,
            fieldLabel: me.customSnippets.settingsDetails.labels.minimumAge,
            labelWidth: 120,
            valueField: 'value',
            displayField: 'text',
            emptyText: me.customSnippets.settingsDetails.labels.noMinimumAge,
            queryMode: 'local',
            mode: 'local',
            editable: false,
            store: Ext.create('Ext.data.SimpleStore', {
                fields: [
                    'text', 'value',
                ],
                data: [
                    [me.customSnippets.settingsDetails.labels.noMinimumAge, null],
                    [me.customSnippets.settingsDetails.labels.minimumAge16, 16],
                    [me.customSnippets.settingsDetails.labels.minimumAge18, 18],
                ],
            }),
            listeners: {
                change: me.onMinimumAgeActive,
                scope: me,
            },
        });

        me.identCheckAge = Ext.create('Ext.form.field.ComboBox', {
            name: 'identCheckAge',
            required: false,
            fieldLabel: me.customSnippets.settingsDetails.labels.identCheck,
            labelWidth: 120,
            valueField: 'value',
            displayField: 'text',
            emptyText: me.customSnippets.settingsDetails.labels.noMinimumAge,
            queryMode: 'local',
            mode: 'local',
            editable: false,
            store: Ext.create('Ext.data.SimpleStore', {
                fields: [
                    'text', 'value',
                ],
                data: [
                    [me.customSnippets.settingsDetails.labels.noMinimumAge, null],
                    [me.customSnippets.settingsDetails.labels.minimumAge16, 16],
                    [me.customSnippets.settingsDetails.labels.minimumAge18, 18],
                ],
            }),
            listeners: {
                change: me.onIdentCheckActive,
                scope: me,
            },
        });

        me.parcelOutletRouting = Ext.create('Ext.form.field.Checkbox', {
            name: 'parcelOutletRouting',
            fieldLabel: me.customSnippets.settingsDetails.labels.parcelOutletRouting,
            helpText: me.customSnippets.tooltips.parcelOutletRoutingHelp,
            required: false,
            checked: false,
            uncheckedValue: false,
            inputValue: true,
        });

        me.postalDeliveryDutyPaid = Ext.create('Ext.form.field.Checkbox', {
            name: 'postalDeliveryDutyPaid',
            fieldLabel: me.customSnippets.settingsDetails.labels.postalDeliveryDutyPaid,
            helpText: me.customSnippets.tooltips.postalDeliveryDutyPaidHelp,
            required: false,
            checked: false,
            uncheckedValue: false,
            inputValue: true,
        });

        me.closestDroppointDelivery = Ext.create('Ext.form.field.Checkbox', {
            name: 'closestDroppointDelivery',
            fieldLabel: me.customSnippets.settingsDetails.labels.closestDroppointDelivery,
            helpText: me.customSnippets.tooltips.closestDroppointDeliveryHelp,
            required: false,
            checked: false,
            uncheckedValue: false,
            inputValue: true,
        });

        me.signedForByRecipient = Ext.create('Ext.form.field.Checkbox', {
            name: 'signedForByRecipient',
            fieldLabel: me.customSnippets.settingsDetails.labels.signedForByRecipient,
            helpText: me.customSnippets.tooltips.signedForByRecipientHelp,
            required: false,
            checked: false,
            uncheckedValue: false,
            inputValue: true,
        });

        /**
         *  Section :: DHL Express Settings Options
         */
        me.saturdayDelivery = Ext.create('Ext.form.field.Checkbox', {
            name: 'saturdayDelivery',
            fieldLabel: me.customSnippets.settingsDetails.labels.saturdayDelivery,
            labelWidth: 120,
            required: false,
            checked: false,
            uncheckedValue: false,
            inputValue: true,
            hidden: true,
        });

        me.isInsuredValue = Ext.create('Ext.form.field.Checkbox', {
            xtype: 'checkboxfield',
            name: 'isInsuredValue',
            fieldLabel: me.customSnippets.settingsDetails.labels.isInsuredValue,
            labelWidth: 120,
            required: false,
            checked: false,
            uncheckedValue: false,
            inputValue: true,
            hidden: true,
            listeners: {
                change: me.onIsInsuredValueChecked,
                scope: me,
            },
        });

        return [
            me.createFormRow({
                rowCls: 'confirm-panel-row-product',
                padding: columnPadding,
                label: {
                    width: labelWidth,
                    text: me.customSnippets.settingsDetails.labels.product,
                },
                items: [
                    me.productComboBox,
                    me.productIcon,
                    Ext.create('Ext.form.field.Display', {
                        width: 10,
                        name: '&nbsp;',
                    }),
                    me.saturdayDelivery,
                    me.createExportDocument,
                ],
            }),
            me.createFormRow({
                rowCls: 'confirm-panel-row-number-of-labels',
                padding: columnPadding,
                label: {
                    width: labelWidth,
                    text: me.snippets.settingsDetails.labels.numberOfLabels,
                    labelStyle: 'margin-top: 0px',
                },
                items: [
                    me.numberOfLabels,
                    me.numberOfLabelsIcon,
                    Ext.create('Ext.form.field.Display', {
                        name: '&nbsp;',
                        flex: 1,
                    }),
                    me.isInsuredValue,
                    me.cashOnDelivery,
                ],
            }),
            me.createFormRow({
                padding: columnPadding,
                items: [
                    me.personalHandover,
                    Ext.create('Ext.form.field.Display', {
                        name: '&nbsp;',
                        flex: 1,
                    }),
                    me.minimumAge,
                ],
            }),
            me.createFormRow({
                padding: columnPadding,
                items: [
                    me.parcelOutletRouting,
                    Ext.create('Ext.form.field.Display', {
                        name: '&nbsp;',
                        flex: 1,
                    }),
                    me.identCheckAge,
                ],
            }),
            me.createFormRow({
                padding: columnPadding,
                items: [
                    me.closestDroppointDelivery,
                    me.postalDeliveryDutyPaid,
                ],
            }),

            me.createFormRow({
                padding: columnPadding,
                items: [
                    me.signedForByRecipient,
                ],
            }),
        ];
    },

    setValues: function () {
        var me = this;
        me.callParent(arguments);

        if (me.settingsContainer) {
            me.settingsContainer.getForm().setValues({
                personalHandover: me.personalHandover,
                minimumAge: me.defaultMinimumAge,
                parcelOutletRouting: me.parcelOutletRouting,
                identCheckAge: me.defaultIdentCheckAge,
                postalDeliveryDutyPaid: me.postalDeliveryDutyPaid,
                closestDroppointDelivery: me.closestDroppointDelivery,
                signedForByRecipient: me.signedForByRecipient,
            });
        }

        // Bind Packing Station data to the UI
        // The data needs to be loaded every time to ensure that changes are synchronized
        // The request is async so it will be loaded & bind in the UI when the data arrives
        if (!me.isReturn) {
            me.dhlPackingStationStore.load({
                scope: me,
                params: {
                    orderId: this.record.get('id'),
                },
                callback: function (records) {
                    if (!records || !records.length) {
                        return;
                    }

                    var record = records[0];
                    // Convert date string from the format d.m.y to y-m-d
                    var preferredDay = record.get('preferredDay').split('.').reverse().join('-');
                    // Join data if exist (is not empty string)
                    var preferredNeighbor = [
                        record.get('preferredNeighborName'),
                        record.get('preferredNeighborAddress'),
                    ].filter(function (val) {
                        return val;
                    }).join('; ');

                    if (record.get('preferredLocation')) {
                        this.preferredLocation.setValue(record.get('preferredLocation'));
                    }

                    if (preferredNeighbor) {
                        this.preferredNeighbour.setValue(preferredNeighbor);
                    }

                    if (preferredDay) {
                        this.datePicker.setValue(new Date(preferredDay));
                    }

                    // Weird ExtJS bug that can occur, set the values to null so the garbage collector can clean the data
                    record = null;
                    preferredDay = null;
                    preferredNeighbor = null;
                },
            });
        }

        /**
         * @deprecated logic to support old Packstation plugin, will be removed with a feature release
         */
        var postNumber = me.record ? me.record[me.dispatchServiceProviderPrefix].postNumber : null;
        if (postNumber != null) {
            me.detailsContainer.getForm().setValues({
                company: postNumber,
            });
        }

        var frankatur = me.record ? me.record[me.dispatchServiceProviderPrefix].frankatur : null;
        if (frankatur && this.frankaturCombobox) {
            this.frankaturCombobox.setValue(frankatur);
        }
        var incoterm = me.record ? me.record[me.dispatchServiceProviderPrefix].incoterm : null;
        if (incoterm && this.incotermCombobox) {
            this.incotermCombobox.setValue(incoterm);
        }
        var saturdayDeliveryForExpress = me.record ? me.record[me.dispatchServiceProviderPrefix].isSaturdayDelivery : null;
        if (saturdayDeliveryForExpress && this.saturdayDelivery) {
            this.saturdayDelivery.setValue(saturdayDeliveryForExpress);
        }
        var toggleInsuredValueCheckbox = false;
        var insuredValueForExpress = me.record ? me.record[me.dispatchServiceProviderPrefix].isInsured : null;
        if (insuredValueForExpress && this.insuredValueField) {
            this.insuredValueField.setValue(me.record.get('invoiceAmount'));
            this.insuredValueCurencyField.setValue(me.record.get('currency'));
            toggleInsuredValueCheckbox = true;
        }
        if (this.isInsuredValue) {
            this.isInsuredValue.setValue(toggleInsuredValueCheckbox);
        }
        var endorsementType = me.record ? me.record[me.dispatchServiceProviderPrefix].endorsementType : null;
        if (endorsementType && this.endorsementType) {
            this.endorsementTypeCombobox.setValue(endorsementType);
        }
    },

    /**
     * @override
     * Returns additional containers to be added to the items of the label confirm panel.
     *
     * @return A list of containers.
     */
    createExtraContainers: function () {
        return this.callParent(arguments).concat([
            this.createAdditionalInformation(),
            this.createAdditionalOptionsForExpress(),
        ]);
    },

    /**
     * Returns a container with additional item to the label confirm panel.
     *
     * Note: This container is only Visible for DHL Paket products
     *
     * @returns Ext.form.Panel
     */
    createAdditionalInformation: function () {
        var me = this;

        me.additionalInformation = Ext.create('Ext.form.Panel', {
            cls: 'confirm-panel-label-type',
            title: me.customSnippets.additionalInformation.title,
            bodyPadding: 5,
            margin: '5 0 0 0',
            layout: 'anchor',
            collapsible: true,
            collapsed: true,
            defaults: {
                anchor: '100%',
            },
            hidden: true,
            items: me.createAdditionalInformationFormRows(130, 10),
        });

        return me.additionalInformation;
    },

    /**
     * Create additional items fields and place them in rows.
     *
     * @param labelWidth The width of the label for the input field.
     * @param columnPadding the padding between the columns.
     * @returns array Additional items as rows.
     */
    createAdditionalInformationFormRows: function (labelWidth, columnPadding) {
        var me = this;

        me.datePicker = Ext.create('Ext.form.field.Date', {
            flex: 1,
            name: 'preferredDayOfDelivery',
            helpText: me.customSnippets.tooltips.preferredDayHelp,
            emptyText: me.customSnippets.additionalInformation.emptyText,
            fieldLabel: me.customSnippets.additionalInformation.preferredDay,
            submitFormat: 'Y-m-d',
            minValue: new Date(),
        });

        me.preferredLocation = Ext.create('Ext.form.field.Text', {
            flex: 1,
            name: 'preferredLocation',
            helpText: me.customSnippets.tooltips.preferredLocation,
            emptyText: me.customSnippets.additionalInformation.emptyPreferredLocation,
            fieldLabel: me.customSnippets.additionalInformation.preferredLocation,
            maxLength: me.maxLength.preferredLocation,
            listeners: {
                change: me.onPreferredLocationChange,
                scope: me,
            },
        });

        me.preferredNeighbour = Ext.create('Ext.form.field.Text', {
            flex: 1,
            name: 'preferredNeighbour',
            helpText: me.customSnippets.tooltips.preferredNeighbour,
            emptyText: me.customSnippets.additionalInformation.emptyPreferredNeighbour,
            fieldLabel: me.customSnippets.additionalInformation.preferredNeighbour,
            maxLength: me.maxLength.preferredNeighbour,
            listeners: {
                change: me.onPreferredNeighbourChange,
                scope: me,
            },
        });

        this.noNeighbourDelivery = Ext.create('Ext.form.field.Checkbox', {
            name: 'noNeighbourDelivery',
            required: false,
            checked: false,
            uncheckedValue: false,
            inputValue: true,
            listeners: {
                change: this.onNoNeighbourDeliveryChange,
                scope: this,
            },
        });

        this.incotermCombobox = Ext.create('Ext.form.field.ComboBox', {
            flex: 1,
            name: 'incoterm',
            fieldLabel: this.customSnippets.additionalInformation.incotermCombobox.label,
            helpText: this.customSnippets.additionalInformation.incotermCombobox.help,
            valueField: 'name',
            displayField: 'description',
            queryMode: 'local',
            mode: 'local',
            editable: false,
            emptyText: '-',
            store: this.incotermStore,
        });

        this.frankaturCombobox = Ext.create('Ext.form.field.ComboBox', {
            flex: 1,
            name: 'frankatur',
            fieldLabel: this.customSnippets.additionalInformation.frankaturCombobox.label,
            helpText: this.customSnippets.additionalInformation.frankaturCombobox.help,
            valueField: 'name',
            displayField: 'description',
            queryMode: 'local',
            mode: 'local',
            editable: false,
            emptyText: '-',
            store: this.frankaturStore,
        });

        this.noNeighbourDeliveryLabel = Ext.create('Ext.form.field.Display', {
            name: 'noNeighbourDeliveryLabel',
            width: labelWidth + 60,
            fieldLabel: this.customSnippets.additionalInformation.noNeighbourDelivery,
            labelStyle: 'width: 180px',
            submitValue: false,
        });

        this.addresseesCustomsReference = Ext.create('Ext.form.field.Text', {
            flex: 1,
            name: 'addresseesCustomsReference',
            fieldLabel: this.customSnippets.additionalInformation.addresseesCustomsReference.label,
            helpText: this.customSnippets.additionalInformation.addresseesCustomsReference.help,
            maxLength: 35,
        });

        this.endorsementTypeCombobox = Ext.create('Ext.form.field.ComboBox', {
            flex: 1,
            name: 'endorsementType',
            required: false,
            fieldLabel: me.customSnippets.additionalInformation.endorsementTypeCombobox.label,
            helpText: me.customSnippets.additionalInformation.endorsementTypeCombobox.help,
            valueField: 'value',
            displayField: 'text',
            emptyText: me.customSnippets.additionalInformation.endorsementTypeCombobox.options.notSpecified,
            queryMode: 'local',
            mode: 'local',
            editable: false,
            store: Ext.create('Ext.data.SimpleStore', {
                fields: [
                    'text', 'value',
                ],
                data: [
                    [me.customSnippets.additionalInformation.endorsementTypeCombobox.options.notSpecified, null],
                    [me.customSnippets.additionalInformation.endorsementTypeCombobox.options.immediate, 'IMMEDIATE'],
                    [me.customSnippets.additionalInformation.endorsementTypeCombobox.options.abandonment, 'ABANDONMENT'],
                ],
            }),
        });

        this.preferredDeliveryTimeRows = [
            this.createFormRow({
                padding: columnPadding,
                items: [
                    this.datePicker,
                    this.preferredLocation,
                ],
            }), this.createFormRow({
                padding: columnPadding,
                items: [
                    this.preferredNeighbour,
                ],
            }),
        ];

        this.noNeighbourDeliveryRow = this.createFormRow({
            padding: columnPadding,
            items: [
                this.noNeighbourDeliveryLabel,
                this.noNeighbourDelivery,
            ],
        });

        this.incotermRow = this.createFormRow({
            padding: columnPadding,
            items: [
                this.incotermCombobox,
            ],
        });

        this.frankaturRow = this.createFormRow({
            padding: columnPadding,
            items: [
                this.frankaturCombobox,
            ],
        });

        this.addresseesCustomsReferenceRow = this.createFormRow({
            padding: columnPadding,
            items: [
                this.addresseesCustomsReference,
            ],
        });

        this.endorsementTypeRow = this.createFormRow({
            padding: columnPadding,
            items: [
                this.endorsementTypeCombobox,
            ],
        });

        return this.preferredDeliveryTimeRows.concat([
            this.noNeighbourDeliveryRow,
            this.incotermRow,
            this.frankaturRow,
            this.addresseesCustomsReferenceRow,
            this.endorsementTypeRow,
        ]);
    },

    /**
     * Returns a container with additional item to the label confirm panel.
     *
     * Note: This container is only Visible for DHL Paket products
     *
     * @returns Ext.form.Panel
     */
    createAdditionalOptionsForExpress: function () {
        var me = this;

        me.additionalExpressInformation = Ext.create('Ext.form.Panel', {
            xtype: 'additionalExressPanel',
            cls: 'confirm-panel-label-type',
            title: me.customSnippets.additionalInformation.title,
            bodyPadding: 5,
            margin: '5 0 0 0',
            layout: 'anchor',
            collapsible: true,
            defaults: {
                anchor: '100%',
            },
            hidden: true,
            items: me.createAdditionalOptionsForExpressFormRows(130, 10),
        });

        return me.additionalExpressInformation;
    },

    /**
     * Create additional items fields for DHL Express and place them in rows.
     *
     * @param labelWidth
     * @param columnPadding
     */
    createAdditionalOptionsForExpressFormRows: function (labelWidth, columnPadding) {
        var me = this;

        me.insuredValueField = Ext.create('Ext.form.field.Number', {
            xtype: 'insurenceAmountNumberfield',
            flex: 3,
            name: 'insuredValue',
            labelWidth: 120,
            fieldLabel: me.customSnippets.settingsDetails.labels.insuredValue,
        });

        me.insuredValueCurencyField = Ext.create('Ext.form.field.Text', {
            xtype: 'insurenceValueCurencyTextfield',
            name: 'insuredValueCurrency',
            fieldLabel: me.snippets.orderAmountInformation.labels.currency,
            labelWidth: 65,
            value: 'EUR',
            maxLength: 3,
            flex: 1,
            allowBlank: false,
        });

        return [me.createFormRow({
            padding: columnPadding,
            items: [
                me.insuredValueField,
                me.insuredValueCurencyField,
            ],
        })];
    },

    /**
     * ========================================
     *  Section:: Listeners
     * ========================================
     */

    /**
     * Event for toggle Insured Value field
     *
     * @param checkbox
     * @param newValue
     */
    onIsInsuredValueChecked: function (checkbox, newValue) {
        var insuredValueContainer = this.additionalExpressInformation;

        if (insuredValueContainer) {
            insuredValueContainer.setDisabled(!newValue);
            insuredValueContainer.setVisible(newValue);
        }
    },

    /**
     * Event listener 'onChange' for minimumAge combobox.
     *
     * @param combobox
     */
    onMinimumAgeActive: function (combobox) {
        if (this.identCheckAge) {
            this.identCheckAge.setDisabled(combobox.value !== null);
        }
    },

    /**
     * Event listener 'onChange' for identCheckAge combobox.
     *
     * @param combobox
     */
    onIdentCheckActive: function (combobox) {
        if (this.minimumAge) {
            this.minimumAge.setDisabled(combobox.value !== null);
        }
    },

    /**
     * Event listener 'onChange' for preferredLocation field.
     */
    onPreferredLocationChange: function () {
        this.updatePreferredOptionsConstraints();
    },

    /**
     * Event listener 'onChange' for preferredNeighbour field.
     */
    onPreferredNeighbourChange: function () {
        this.updatePreferredOptionsConstraints();
    },

    /**
     * Event listener 'onChange' for noNeighbourDelivery field.
     *
     * @param checkbox
     */
    onNoNeighbourDeliveryChange: function (checkbox) {
        if (this.preferredNeighbour) {
            // Disabled preferredNeighbour field if no neighbour option
            // is activated
            this.preferredNeighbour.setDisabled(checkbox.getValue());
        }
    },

    /**
     * @Override from ShippingCommon
     */
    onStateStoreLoad: function () {
        var newValue = this.statesStore.proxy.extraParams.countryId;
        var germanyId = 2;

        this.callParent(arguments);

        // Because DHL doesn't print State names for Germany
        if (newValue === germanyId) {
            this.state.hide();
        }
    },

    /**
     * @override
     * Update field constraints when the product was changed using the combobox.
     */
    productChanged: function (field, newValue) {
        this.callParent(arguments);

        var newProduct = this.productStore.findRecord('id', newValue, false, false, false, true);

        if (!newProduct) {
            return;
        }

        Ext.suspendLayouts();
        this.updateSettingsVisibility(newProduct);
        this.updateAdditionalInformationVisibility(newProduct);
        this.updateExpressSettingsVisibility(newProduct);
        Ext.resumeLayouts(true);
    },

    /**
     * @override
     */
    getExtraSettings: function () {
        if (!this.additionalInformation || !this.additionalExpressInformation) {
            return null;
        }

        return Ext.apply(
            this.callParent(arguments),
            this.additionalInformation.getForm().getValues(),
            this.additionalExpressInformation.getForm().getValues()
        );
    },

    /**
     * ========================================
     *  Section:: Update Visibility for fields
     * ========================================
     */

    /**
     * The visibility and constraints for the Additional Information panel.
     *
     * NOTE: Depending on the Screen size it will be folded/un-foldede by default
     *
     * @param { Shopware.apps.ViisonDHLShipping.model.Product } newProduct DHL Product Code
     */
    updateAdditionalInformationVisibility: function (newProduct) {
        var productIdentifier = newProduct.get('product');
        // Don't break the execution with Exceptions
        if (!this.additionalInformation || !this.additionalInformation.getForm) {
            return;
        }

        this.updateFrankaturRowVisibility(productIdentifier);

        var showIncotermCombobox = this.createExportDocument.getValue() || newProduct.get('code') === 'EXP';
        this.updateIncotermComboboxVisibility(showIncotermCombobox, newProduct.get('code') === 'EXP');

        this.updateAddresseesCustomsReferenceVisibility(this.createExportDocument.getValue());

        this.updateAdditionalInformationFieldVisibility(newProduct.get('product'));
        this.updateAdditionalInformationContainerVisibility();

        var additionalInformationContainerVisible = this.additionalInformationContainerVisible();

        if (this.additionalInformation && additionalInformationContainerVisible) {
            var viewPortSize = this.getViewPortSizeWithoutShopwareNavbarHeight();
            var panelHeight = this.getLabelConfirmWindowHeightWithExpandedInformationPanel(
                this.additionalInformation.up('window').getHeight()
            );

            // Check if the ViewPort height is smaller than the panel height with expanded Additional Information
            this.togglePanelCollapse(this.additionalInformation, panelHeight >= viewPortSize);
        }
    },

    /**
     * @returns { boolean }
     */
    additionalInformationContainerVisible: function () {
        return this.additionalInformation.getForm().getFields().items.some(function (field) {
            return !field.isDisabled();
        });
    },

    /**
     * @param { string } productIdentifier
     * @returns { boolean }
     */
    productSupportsFrankatur: function (productIdentifier) {
        var productsWithFrankatur = ['V54EPAK'];

        return productsWithFrankatur.some(function (productWithFrankatur) {
            return productIdentifier === productWithFrankatur;
        });
    },

    /**
     * @param { string } productIdentifier
     */
    updateFrankaturRowVisibility: function (productIdentifier) {
        var productSupportsFrankatur = this.productSupportsFrankatur(productIdentifier);

        this.frankaturRow.setVisible(productSupportsFrankatur);
        this.frankaturRow.setDisabled(!productSupportsFrankatur);
    },

    /**
     * @param { string } productIdentifier
     * @returns { boolean }
     */
    productSupportsParcelOutletRouting: function (productIdentifier) {
        var productsWithParcelOutletRouting = ['V01PAK', 'V01PRIO', 'V62WP'];

        return productsWithParcelOutletRouting.some(function (productWithParcelOutletRouting) {
            return productIdentifier === productWithParcelOutletRouting;
        });
    },

    /**
     * @param { string } productIdentifier
     */
    updateParcelOutletRoutingRowVisibility: function (productIdentifier) {
        var productSupportsParcelOutletRouting = this.productSupportsParcelOutletRouting(productIdentifier);

        this.getForm().findField('parcelOutletRouting').setVisible(productSupportsParcelOutletRouting);
        this.getForm().findField('parcelOutletRouting').setDisabled(!productSupportsParcelOutletRouting);
    },

    /**
     * Determines whether the additional information row has enabled and visible items and enables the container
     * accordingly.
     */
    updateAdditionalInformationContainerVisibility: function () {
        var additionalInformationContainerVisible = this.additionalInformationContainerVisible();

        this.additionalInformation.setVisible(additionalInformationContainerVisible);
        this.additionalInformation.setDisabled(!additionalInformationContainerVisible);
    },

    productSupportedDeliveryServices: function (productIdentifier) {
        var productsWithPreferredNeighbour = ['V01PAK', 'V01PRIO', 'V62WP'];
        var productsWithPreferredLocation = ['V01PAK', 'V01PRIO', 'V62WP'];
        var productsWithPreferredDay = ['V01PAK', 'V01PRIO'];
        var productsWithNoNeighbourDelivery = ['V01PAK', 'V01PRIO'];
        var productsWithEndorsement = ['V53WPAK'];

        return {
            preferredNeighbour: productsWithPreferredNeighbour.includes(productIdentifier),
            preferredLocation: productsWithPreferredLocation.includes(productIdentifier),
            preferredDay: productsWithPreferredDay.includes(productIdentifier),
            noNeighbourDelivery: productsWithNoNeighbourDelivery.includes(productIdentifier),
            endorsement: productsWithEndorsement.includes(productIdentifier),
        };
    },

    updateAdditionalInformationFieldVisibility: function (productIdentifier) {
        var productSupportedDeliveryServices = this.productSupportedDeliveryServices(productIdentifier);
        var additionalInformationForm = this.additionalInformation.getForm();

        this.noNeighbourDeliveryRow.setVisible(productSupportedDeliveryServices.noNeighbourDelivery);
        this.noNeighbourDeliveryRow.setDisabled(!productSupportedDeliveryServices.noNeighbourDelivery);
        additionalInformationForm.findField('preferredDayOfDelivery').setVisible(productSupportedDeliveryServices.preferredDay);
        additionalInformationForm.findField('preferredDayOfDelivery').setDisabled(!productSupportedDeliveryServices.preferredDay);
        additionalInformationForm.findField('&nbsp;').setVisible(productSupportedDeliveryServices.preferredDay);
        additionalInformationForm.findField('&nbsp;').setDisabled(!productSupportedDeliveryServices.preferredDay);
        additionalInformationForm.findField('preferredNeighbour').setVisible(productSupportedDeliveryServices.preferredNeighbour);
        additionalInformationForm.findField('preferredNeighbour').setDisabled(!productSupportedDeliveryServices.preferredNeighbour);
        additionalInformationForm.findField('preferredLocation').setVisible(productSupportedDeliveryServices.preferredLocation);
        additionalInformationForm.findField('preferredLocation').setDisabled(!productSupportedDeliveryServices.preferredLocation);
        this.endorsementTypeRow.setVisible(productSupportedDeliveryServices.endorsement);
        this.endorsementTypeRow.setDisabled(!productSupportedDeliveryServices.endorsement);
    },

    /**
     * @param field
     * @param { boolean } newValue
     */
    createExportDocumentChanged: function (field, newValue) {
        this.updateIncotermComboboxVisibility(newValue);
        this.updateAddresseesCustomsReferenceVisibility(newValue);
        this.updateAdditionalInformationContainerVisibility();
    },

    /**
     * @param { boolean } visible
     */
    updateIncotermComboboxVisibility: function (visible, isExpress) {
        if (isExpress) {
            this.incotermCombobox.bindStore(this.incotermExpressStore);
        } else {
            this.incotermCombobox.bindStore(this.incotermStore);
        }

        this.incotermCombobox.setVisible(visible);
        this.incotermCombobox.setDisabled(!visible);
        this.incotermCombobox.getStore().load();
    },

    /**
     * @param { boolean } visible
     */
    updateAddresseesCustomsReferenceVisibility: function (visible) {
        this.addresseesCustomsReference.setVisible(visible);
        this.addresseesCustomsReference.setDisabled(!visible);
    },

    /**
     * Get viewport size without Shopware nav-bar height
     * @return int
     */
    getViewPortSizeWithoutShopwareNavbarHeight: function () {
        var SHOPWARE_NAVBAR_HEIGHT_IN_PIXELS = 50;

        return Ext.getBody().getViewSize().height - SHOPWARE_NAVBAR_HEIGHT_IN_PIXELS;
    },

    /**
     * Calculate the panel height depending on if some sections are collapsed
     *
     * @param Ext.Panel panel
     * @param boolean isCollapsed
     * @return int
     */
    getLabelConfirmWindowHeightWithExpandedInformationPanel: function (panelHeight) {
        // The size isn't 100% accurate, outside factors are added to (borders, padding out, margins ...)
        var EXPANDED_INFORMATION_HEIGHT_IN_PIXELS = 140;

        return panelHeight + EXPANDED_INFORMATION_HEIGHT_IN_PIXELS;
    },

    /**
     * Expand or collapse the given panel.
     *
     * @param panel
     * @param collapse
     */
    togglePanelCollapse: function (panel, collapse) {
        if (!panel || (!panel.collapse || !panel.expand)) {
            return;
        }

        // We need to check for panel.collapsed because of a weird toggle ExtJS Bug
        if (panel.collapsed && !collapse) {
            panel.expand();
        } else if (!panel.collapsed && collapse) {
            panel.collapse();
        }
    },

    /**
     * Disable settings options where it is not supported
     *
     * @param { Shopware.apps.ViisonDHLShipping.model.Product } newProduct DHL Product Code
     */
    updateSettingsVisibility: function (newProduct) {
        var productCode = newProduct.get('code');
        var disabledProductCodes = this.dhlServiceProductConstraints.settings.disabledForCode;
        var hideFields = (productCode && disabledProductCodes.indexOf(productCode) !== -1);

        var productIdentifier = newProduct.get('product');
        var dhlServiceProductConstraintSettings = this.dhlServiceProductConstraints.settings;
        var hideCashOnDelivery = !dhlServiceProductConstraintSettings.supportsCashOnDelivery.includes(productIdentifier);
        var hidePersonalHandover = !dhlServiceProductConstraintSettings.supportsPersonalHandover.includes(productIdentifier);
        var hideMinimumAge = !dhlServiceProductConstraintSettings.supportsVisualAgeCheck.includes(productIdentifier);
        var hideIdentCheck = !dhlServiceProductConstraintSettings.supportsIdentCheck.includes(productIdentifier);
        var hidePostalDeliveryDutyPaid = !dhlServiceProductConstraintSettings.supportsPostalDeliveryDutyPaid.includes(productIdentifier);
        var hideClosestDroppointDelivery = !dhlServiceProductConstraintSettings.supportsClosestDroppointDelivery.includes(productIdentifier);
        var hideSignedForByRecipient = !dhlServiceProductConstraintSettings.supportsSignedForByRecipient.includes(productIdentifier);

        this.toggleHelper([this.createExportDocument], hideFields);
        this.toggleHelper([this.minimumAge], hideMinimumAge);
        this.toggleHelper([this.getForm().findField('personalHandover')], hidePersonalHandover);
        this.toggleHelper([this.cashOnDelivery], hideCashOnDelivery);
        this.updateParcelOutletRoutingRowVisibility(productIdentifier);
        this.toggleHelper([this.identCheckAge], hideIdentCheck);
        this.toggleHelper([this.getForm().findField('postalDeliveryDutyPaid')], hidePostalDeliveryDutyPaid);
        this.toggleHelper([this.getForm().findField('closestDroppointDelivery')], hideClosestDroppointDelivery);
        this.toggleHelper([this.getForm().findField('signedForByRecipient')], hideSignedForByRecipient);

        // Disable the createExportDocument field for frankatur enabled products as well.
        var productSupportsFrankatur = this.productSupportsFrankatur(productIdentifier);
        if (productSupportsFrankatur) {
            this.createExportDocument.setValue(false);
            this.createExportDocument.setVisible(false);
            this.createExportDocument.setDisabled(true);
        }

        // If the fields need to be disabled, reset any dependencies linked to it (like panel visibility)
        if (hideCashOnDelivery) {
            this.cashOnDelivery.setValue(false);
        }
    },

    /**
     * Update constraints for preferred neighbour and location
     */
    updatePreferredOptionsConstraints: function () {
        // DHL doesn't allow booth fields to be used at the same time
        if (this.preferredNeighbour) {
            this.preferredNeighbour.setDisabled(this.preferredLocation.getValue());
        }
        if (this.preferredLocation) {
            this.preferredLocation.setDisabled(this.preferredNeighbour.getValue());
        }
    },

    /**
     * Disable express options where it is not supported
     *
     * @param { Shopware.apps.ViisonDHLShipping.model.Product } newProduct DHL Product Code
     */
    updateExpressSettingsVisibility: function (newProduct) {
        var productCode = newProduct.get('code');
        var product = newProduct.get('product');
        var dhlExpressConstraints = this.dhlServiceProductConstraints.express;
        var enabledProductCodes = dhlExpressConstraints.enabledForCode;
        var hideExpressServiceField = (productCode && enabledProductCodes.indexOf(productCode) === -1);
        var hideSaturdayDeliveryField = !(
            !hideExpressServiceField
            && dhlExpressConstraints.supportsSaturdayDelivery.includes(product)
        );

        this.toggleHelper([this.isInsuredValue], hideExpressServiceField);
        this.toggleHelper([this.saturdayDelivery], hideSaturdayDeliveryField);

        // If the fields need to be enabled, reset any dependencies linked to it (like panel visibility)
        if (hideExpressServiceField) {
            this.isInsuredValue.setValue(false);
        }
        if (hideSaturdayDeliveryField) {
            this.saturdayDelivery.setValue(false);
        }
    },

    /**
     * Update constraints for preferred neighbour and location
     */

    /**
     * ========================================
     *  Section:: Helper methods
     * ========================================
     */

    /**
     * Toggle disable & visibility for all fields.
     *
     * @param array fields
     * @param bool isRule
     */
    toggleHelper: function (fields, isRule) {
        this.toggleDisableOptionInFields(fields, isRule); // Disable: true - disable, false - enable
        this.toggleVisibilityOptionInFields(fields, !isRule); // Visibility: true - show, false - hide
    },

    /**
     * Toggle option for disable for all fields.
     *
     * @param array fields
     * @param bool  isDisabled The toggle value for disable
     */
    toggleDisableOptionInFields: function (fields, isDisabled) {
        if (!fields || !fields.forEach) {
            return;
        }

        fields.forEach(function (item) {
            if (item.setDisabled) {
                item.setDisabled(isDisabled);
            }
        });
    },

    /**
     * Toggle option for visibility for all given fields.
     *
     * @param array fields
     * @param bool  isDisabled The toggle value for disable
     */
    toggleVisibilityOptionInFields: function (fields, isVisible) {
        if (!fields || !fields.forEach) {
            return;
        }

        fields.forEach(function (item) {
            if (item.setVisible) {
                item.setVisible(isVisible);
            }
        });
    },

    /**
     * Dimension constraints used inside the order view
     *
     * Defined: The '$dimensionConstraints' is coming from viewParams() inside backend order Controller
     *
     * Note: The dimensionConstraints are defined at the end of the class because syntax's highlighting is seeing this
     *       as a JS error and so all the editor file is red
     */
    dimensionConstraints: Ext.JSON.decode('{$dimensionConstraints|@json_encode}') || [],

});
