/*
 *  Copyright 2020 Anyware Services
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */
/**
 * This class controls a ribbon button to import archives
 */
Ext.define('Ametys.plugins.contentio.archive.ImportArchiveController', {
    extend: 'Ametys.ribbon.element.ui.ButtonController', 
    
    /**
     * @private
     * @property {Ametys.window.DialogBox} _dialog The dialog box.
     */
    _dialog: null,
    
    /**
     * @property {Object[]} The merge policy options
     * @readonly
     */
    MERGE_POLICY_OPTIONS: null,
    
    /**
     * Opens the dialog box to choose options for archive's import
     */
    openImportDialog: function()
    {
        if (this.MERGE_POLICY_OPTIONS == null)
        {
            this._initMergePolicies(createDialogAndShow);
        }
        else
        {
            createDialogAndShow.call(this);
        }
        
        function createDialogAndShow()
        {
            // Re-create dialog box each time the button is re-clicked
            this._createDialog();
            this._dialog.show();
        }
    },
    
    /**
     * @private
     * Init MERGE_POLICY_OPTIONS
     * @param {Function} cb The callback function
     */
    _initMergePolicies: function(cb)
    {
        this.serverCall(
            'getMergePolicies', 
            [],
            Ext.bind(function(mergePolicies)
            {
                this.MERGE_POLICY_OPTIONS = mergePolicies;
                cb.call(this);
            }, this)
        );
    },
    
    /**
     * @private
     * Creates the dialog box
     */
    _createDialog: function()
    {
        this._dialog = Ext.create('Ametys.window.DialogBox', {
            title: "{{i18n PLUGINS_CONTENTIO_ARCHIVE_IMPORT_DIALOG_TITLE}}",
            iconCls: 'ametysicon-gear39',
            
            width: 450,
            maxHeight: 600,
            layout: {
                type: "vbox",
                align: "stretch"
            },
            
            defaultFocus: 'form',
            items: this._getDialogItems(),
            
            referenceHolder: true,
            defaultButton: 'validate',
            closeAction: 'destroy',
            
            buttons:  [{
                reference: 'validate',
                itemId: 'button-validate',
                text: "{{i18n PLUGINS_CONTENTIO_ARCHIVE_IMPORT_DIALOG_OK_BTN}}",
                handler: this._validate,
                scope: this,
                disabled: true
            }, {
                itemId: 'button-cancel',
                text: "{{i18n PLUGINS_CONTENTIO_ARCHIVE_IMPORT_DIALOG_CANCEL_BTN}}",
                handler: this._cancel,
                scope: this
            }]
        });
    },
    
    /**
     * @private
     * Gets the items of the dialog box
     * @return {Ext.Component[]} The items of the dialog box
     */
    _getDialogItems: function()
    {
        var formPanel = {
            xtype: 'form',
            itemId: 'form',
            border: false,
            
            defaults: {
                cls: 'ametys',
                labelAlign: 'right',
                labelSeparator: '',
                labelWidth: 120,
                anchor: '100%'
            },
            items: [{
                xtype: 'combobox',
                itemId: 'archive',
                name: 'archive',
                fieldLabel: "{{i18n PLUGINS_CONTENTIO_ARCHIVE_IMPORT_SCHEDULABLE_PARAM_ARCHIVE_LABEL}}",
                ametysDescription: "{{i18n PLUGINS_CONTENTIO_ARCHIVE_IMPORT_SCHEDULABLE_PARAM_ARCHIVE_DESC}}",
                store: this._getArchivesStoreCfg(),
                listeners: {
                    'select': this._onArchiveSelected,
                    scope: this
                },
                valueField: 'archiveName',
                displayField: 'archiveName',
                allowBlank: false,
                forceSelection: true
            }, {
                xtype: 'orderable-tagfield',
                itemId: 'elements',
                name: 'elements',
                fieldLabel: "{{i18n PLUGINS_CONTENTIO_ARCHIVE_IMPORT_SCHEDULABLE_PARAM_ELEMENTS_LABEL}}",
                ametysDescription: "{{i18n PLUGINS_CONTENTIO_ARCHIVE_IMPORT_SCHEDULABLE_PARAM_ELEMENTS_DESC}}",
                emptyText: "{{i18n PLUGINS_CONTENTIO_ARCHIVE_IMPORT_DIALOG_FIELD_ELEMENTS_ALL_OPTION}}",
                multiSelect: true,
                store: this._getElementsStoreCfg(),
                valueField: 'key',
                displayField: 'label',
                disabled: true
            }, {
                xtype: 'combobox',
                itemId: 'mergePolicy',
                name: 'mergePolicy',
                fieldLabel: "{{i18n PLUGINS_CONTENTIO_ARCHIVE_IMPORT_SCHEDULABLE_PARAM_MERGE_POLICY_LABEL}}",
                ametysDescription: this._getMergePolicyDescription(),
                store: this.MERGE_POLICY_OPTIONS,
                value: this.MERGE_POLICY_OPTIONS[0]['value'], // initial value with first option available
                valueField: 'value',
                displayField: 'label',
                allowBlank: false,
                forceSelection: true
            }]
        };
        
        return [formPanel];
    },
    
    /**
     * @private
     * Gets the description of the 'merge policy' field
     * @return {String} the description of the 'merge policy' field
     */
    _getMergePolicyDescription: function()
    {
        var options = this.MERGE_POLICY_OPTIONS;
        var t = new Ext.XTemplate([
            "{{i18n PLUGINS_CONTENTIO_ARCHIVE_IMPORT_DIALOG_FIELD_MERGE_POLICY_DESC_INTRO}}",
            "<ul>",
                "<tpl for='.'>",
                    "<li><b>{label}</b>{{i18n PLUGINS_CONTENTIO_ARCHIVE_IMPORT_DIALOG_FIELD_MERGE_POLICY_DESC_OPTIONS_SEP}}{desc}</li>",
                "</tpl>",
            "</ul>"
        ]);
        return t.apply(options);
    },

    /**
     * @private
     * Gets the configuration of the 'archive' store
     * @return {Object} The configuration of the store
     */
    _getArchivesStoreCfg: function()
    {
        return {
            fields: ['archiveName'],
            proxy: {
                type: 'ametys',
                serverCaller: this,
                methodName: 'getArchiveFiles',
                methodArguments: [],
                reader: {
                    type: 'json'
                }
            },
            sorters: [{property: 'label', direction: 'ASC'}]
        };
    },
    
    /**
     * @private
     * Called when a new archive is selected, in order to update the 'import elements' combobox
     */
    _onArchiveSelected: function()
    {
        var elementsCombo = this._getFormPanel().items.getByKey('elements');
        var okBtn = this._dialog.down('#button-validate');
        if (elementsCombo.isDisabled())
        {
            elementsCombo.enable();
        }
        if (okBtn.isDisabled())
        {
            okBtn.enable();
        }
        
        // If it is disabled, do not launch a reload, as it will re-load on click anyway (I don't know wwhy)
        var currentValues = Ext.Array.from(elementsCombo.getValue());
        elementsCombo.getStore().load(function(records) {
            var remainingSelection = Ext.Array.filter(records || [], function(item) {
                return Ext.Array.contains(currentValues, item.get('key'));
            });
            elementsCombo.setValue(remainingSelection);
            if (!records)
            {
                disableElementsInCaseOfError();
            }
        });
        
        function disableElementsInCaseOfError()
        {
            elementsCombo.disable();
            okBtn.disable();
        }
    },
    
    /**
     * @private
     * Gets the configuration of the 'import elements' store
     * @return {Object} The configuration of the store
     */
    _getElementsStoreCfg: function()
    {
        return {
            store: 'store',
            fields: ['key', 'label'],
            autoLoad: false,
            proxy: {
                type: 'ametys',
                serverCaller: this,
                methodName: 'getAvailablePartialImports',
                methodArguments: ['archiveName'],
                reader: {
                    type: 'json'
                }
            },
            listeners: {
                'beforeload': function(store, operation)
                {
                    var archiveName = this._getFormPanel().items.getByKey('archive').getValue();
                    operation.setParams(Ext.apply(operation.getParams() || {}, {
                        archiveName: archiveName
                    }));
                },
                scope: this
            }
        };
    },
    
    /**
     * @private
     * Handler when clicking on 'cancel' button
     */
    _cancel: function()
    {
        this._dialog.hide();
    },

    /**
     * @private
     * Handler for 'Ok' action
     */
    _validate: function()
    {
        var isValidForm = this._getFormPanel().isValid();
        if (!isValidForm)
        {
            return;
        }
        
        var values = this._getFormPanel().getValues();
        
        this.serverCall(
            'scheduleImport', 
            [values],
            Ext.bind(afterSchedule, this),
            {
                waitMessage: {
                    target: this._dialog
                }
            }
        );
        
        function afterSchedule(response)
        {
            if (response['ok'] === true)
            {
                this._dialog.close();
                Ametys.notify({
                    title: "{{i18n PLUGINS_CONTENTIO_ARCHIVE_IMPORT_NOTIFY_TITLE}}",
                    description: "{{i18n PLUGINS_CONTENTIO_ARCHIVE_IMPORT_NOTIFY_DESC}}"
                });
            }
            else
            {
                Ext.Msg.show({
                    title:"{{i18n PLUGINS_CONTENTIO_ARCHIVE_IMPORT_ERROR_TITLE}}",
                    message: "{{i18n PLUGINS_CONTENTIO_ARCHIVE_IMPORT_ERROR_MSG}}",
                    buttons: Ext.Msg.OK,
                    icon: Ext.Msg.ERROR
                });
            }
        };
    },
    
    /**
     * @private
     * Gets the configurable form panel of the dialog box.
     * @return {Ametys.form.ConfigurableFormPanel} The configurable form panel
     */
    _getFormPanel: function()
    {
        return this._dialog.items.getByKey('form');
    }
    
});