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

/**
 * Singleton class defining the file import function.
 * @private
 */
Ext.define('Ametys.plugins.contentio.ImportCSVActions', {
    singleton: true,

    /**
     * @cfg {String} [serverRole="org.ametys.plugins.contentio.csv.ImportCSVFile"] The role of server component which handle the import
     */
    
    /**
     * @cfg {String} [helperServerRole="org.ametys.plugins.contentio.csv.ImportCSVFileHelper"] The role of server component which prepares the import
     */
    
    /**
     * @property {Ext.form.Panel} _formPanel The dialog box form panel.
     * @private
     */
    _formPanel: null,
    
    /**
     * @property {Ametys.window.DialogBox} _box The action dialog box.
     * @private
     */
    _box: null,

    /**
	 * @private
	 * @property {Object} _parameters the mapping of default parameters
	 */
    _parameters: {},
    
    /**
	 * @private
	 * @property {Object} _parameters the mapping of default parameters
	 */
    _contentTypes: null,
    
    /**
     * Called when the button is pressed
     * @param {Ametys.ribbon.element.ui.ButtonController} controller The controller for the ui debug button
     */
    act: function(controller)
    {
    	this.open(controller.getInitialConfig());
    },
    
    /**
     * Open dialog to import CSV file
     * @param {Object} config The initial configuration
     */
    open: function(config)
    {
        let localConfig = window.structuredClone(config || {});
        
        this.serverRole = localConfig.serverRole || "org.ametys.plugins.contentio.csv.ImportCSVFile";
        
        localConfig.helperServerRole = localConfig.helperServerRole || "org.ametys.plugins.contentio.csv.ImportCSVFileHelper";
        this.helperServerRole = localConfig.helperServerRole;
        
		Ametys.data.ServerComm.callMethod({
			role: this.helperServerRole,
			methodName: "getImportCSVParametersValues",
			parameters: [localConfig["content-type"]],
			callback: {
                handler: Ext.bind(this._createDialogBox, this),
				arguments: {
					config: localConfig
				},
	            scope: this
	        },
			errorMessage: {
				category: this.self.getName(),
                msg: Ext.String.format("{{i18n PLUGINS_CONTENTIO_CONTENT_IMPORT_ERROR_TEXT}}", localConfig.fileName)
			}
		});
		
    },
    
    _createDialogBox: function(paramsValues, args)
    {
        this._formPanel = this._createFormPanel(paramsValues, args.config);
        
        this._box = Ext.create('Ametys.window.DialogBox', {
            title: "{{i18n PLUGINS_CONTENTIO_CONTENT_IMPORT_DIALOG_TITLE}}",
            iconCls: 'ametysicon-file-extension-csv',
            layout: {
	            type: 'vbox',
	            align : 'stretch',
	            pack  : 'start'
	        },
            width: 500,
            
            items: [this._formPanel],
            
            closeAction: 'destroy',
            buttons: [{
                text: "{{i18n PLUGINS_CONTENTIO_CONTENT_IMPORT_DIALOG_OK}}",
                handler: Ext.bind(this._ok, this, [args.config], false),
                scope: this
            }, {
                text: "{{i18n PLUGINS_CONTENTIO_CONTENT_IMPORT_DIALOG_CANCEL}}",
                handler: this._cancel,
                scope: this
            }]
        });
        
        this._box.show();
    },
    
    /**
     * Create the upload dialog's form panel.
     * @param {Object} paramsValues the values to use to iniatilize the import parameters
     * @param {Array} paramValues.availableContentTypes the list of available content types
     * @param {String} paramValues.defaultRecipient the default email address to send notification when the import is over
     * @param {Object} config the initial config
     * @return {Ext.form.Panel} The upload dialog's form panel.
     * @private
     */
    _createFormPanel: function(paramsValues, config)
    {
        var contentTypes = paramsValues.availableContentTypes;
        var defaultRecipient = paramsValues.defaultRecipient;
        
        return Ext.create('Ext.form.Panel', {
            bodyStyle: 'padding:5px',
            
            defaultType: 'textfield',

            defaults: {
                cls: 'ametys',
                labelSeparator: '',
                labelAlign: 'right',
                labelWidth: 160,
                anchor: '100%'
            },
            
            border: false,
            scollable: true,
            items: [{
                xtype: 'fileuploadfield',
                name: 'file',
                fieldLabel: "* {{i18n PLUGINS_CONTENTIO_CONTENT_IMPORT_DIALOG_FILEFIELD_LABEL}}",
                ametysDescription: "{{i18n PLUGINS_CONTENTIO_CONTENT_IMPORT_DIALOG_FILEFIELD_LABEL}}",
                emptyText: "{{i18n PLUGINS_CONTENTIO_CONTENT_IMPORT_DIALOG_FILEFIELD_EMPTY}}",
                buttonText: "{{i18n PLUGINS_CONTENTIO_CONTENT_IMPORT_DIALOG_FILEFIELD_BUTTON}}",
                allowBlank: false
            },
            {
                fieldLabel: "* {{i18n PLUGINS_CONTENTIO_CONTENT_IMPORT_DIALOG_SEPARATION_LABEL}}",
                ametysDescription: "{{i18n PLUGINS_CONTENTIO_CONTENT_IMPORT_DIALOG_SEPARATION_DESCRIPTION}}",
                xtype: 'textfield',
                name: 'separating-char',
                allowBlank: false,
                value: ';',
                maxLength: 1
            },
            {
                fieldLabel: "* {{i18n PLUGINS_CONTENTIO_CONTENT_IMPORT_DIALOG_ESCAPING_LABEL}}",
                ametysDescription: "{{i18n PLUGINS_CONTENTIO_CONTENT_IMPORT_DIALOG_ESCAPING_DESCRIPTION}}",
                xtype: 'textfield',
                name: 'escaping-char',
                allowBlank: false,
                value: '"',
                maxLength: 1
            },
            {
                fieldLabel: "* {{i18n PLUGINS_CONTENTIO_CONTENT_IMPORT_DIALOG_CONTENT_TYPE_LABEL}}",
                ametysDescription: "{{i18n PLUGINS_CONTENTIO_CONTENT_IMPORT_DIALOG_CONTENT_TYPE_DESCRIPTION}}",
                xtype: "combobox",
                store: {
                    fields: ['label', 'id'],
                    data: contentTypes,
                    sorters: [{
                         property: 'label',
                         direction: 'ASC'
                     }]
                },
                queryMode: 'local',
                displayField: 'label',
                valueField: 'id',
                name: 'contentType',
                allowBlank: false,
                forceSelection: true,
                allowOnlyWhitespace: false,
                hidden: contentTypes.length == 1 || config["content-type"],
                value: contentTypes.length == 1 ? contentTypes[0].id : config["content-type"]
            },
            {
                fieldLabel: "{{i18n PLUGINS_CONTENTIO_CONTENT_IMPORT_DIALOG_RECIPIENT_LABEL}}",          
                ametysDescription: "{{i18n PLUGINS_CONTENTIO_CONTENT_IMPORT_DIALOG_RECIPIENT_DESCRIPTION}}",     
                xtype: 'textfield',
                name: 'recipient',
                allowBlank: true,
                value: defaultRecipient
            }]
        });
    },
    
    /**
     * Handle the OK button by submitting the form.
     * @param {Object} config the initial config
     * @private
     */
    _ok: function(config)
    {
        var form = this._formPanel.getForm();
               
        if (!form.isValid())
        {
            return;
        }
        var formValues = this._formPanel.getValues();
        

        if (formValues["separating-char"] == formValues["escaping-char"])
        {
			Ametys.Msg.show({
				title: "{{i18n PLUGINS_CONTENTIO_CONTENT_IMPORT_ERROR_TITLE}}",
				msg: "{{i18n PLUGINS_CONTENTIO_CONTENT_IMPORT_ERROR_SAME_CHAR}}",
				buttons: Ext.Msg.OK,
				icon: Ext.Msg.ERROR
			});
            return;
        }
        
        var parameters = [formValues["escaping-char"],
                          formValues["separating-char"],
                          formValues["contentType"],
                          form.findField('file').getFiles()[0]];
        
        Ametys.data.ServerComm.callMethod({
                role: this.serverRole, 
                methodName: 'importCSVFile',
                parameters: parameters,
                priority: Ametys.data.ServerComm.PRIORITY_LONG_REQUEST,
                callback: {
                    handler: this._okCb,
                    scope: this,
                    arguments: {
                        form: form,
                        config: config
                    }
                },
                errorMessage: "{{i18n plugin.core-ui:PLUGINS_CORE_UI_FILE_HANDLE_ADD_RENAME_UPDATE_ERROR}}",
                progressMessage: {
                    title: "{{i18n PLUGINS_CONTENTIO_CONTENT_IMPORT_DIALOG_WAIT_TITLE}}",
                    msg: "{{i18n PLUGINS_CONTENTIO_CONTENT_IMPORT_DIALOG_WAIT_MSG}}"
                }
            });
    },
    
    /**
     * @private
     * This function is called after the resources have tried to be imported
     * @param {Object} result The results
     */
    _okCb: function(result, arguments)
    {
        if (result.success)
        {
            this._success(result, arguments.form, arguments.config);
        }
        else
        {
            this._failure(result, arguments.form, arguments.config);
        }
    },
    
    /**
     * Callback fired when the property has been successfully added.
     * @param {Object} result The results
     * @param {Ext.form.Basic} form The form that requested the action.
     * @param {Object} config the initial config
     * @private
     */
    _success: function(result, form, config)
    {
        this._box.hide();
           
        config = Ext.apply(result, config, form.getValues());
        Ametys.plugins.contentio.ConfigureCSVImport.open(config)
    },
    
    /**
     * Callback fired when the property creation has failed.
     * @param {Object} result The results
     * @param {Ext.form.Basic} form The form that requested the action.
     * @param {Object} config the initial config
     * @private
     */
    _failure: function(result, form, config)
    {
    	var error = result ? result.error : '';

		if (error == 'rejected')
		{

			Ametys.Msg.show({
				title: "{{i18n PLUGINS_CONTENTIO_CONTENT_IMPORT_ERROR_TITLE}}",
				msg: "{{i18n PLUGINS_CONTENTIO_CONTENT_IMPORT_ERROR_REJECTED}}",
				buttons: Ext.Msg.OK,
				icon: Ext.Msg.ERROR
			});
		}
		else if (error == 'invalid-extension')
		{
			Ametys.Msg.show({
				title: "{{i18n PLUGINS_CONTENTIO_CONTENT_IMPORT_ERROR_TITLE}}",
				msg: "{{i18n PLUGINS_CONTENTIO_CONTENT_IMPORT_ERROR_INVALID_EXTENSION}}",
				buttons: Ext.Msg.OK,
				icon: Ext.Msg.ERROR
			});
		}
		else if (error == 'same-char')
		{
			Ametys.Msg.show({
				title: "{{i18n PLUGINS_CONTENTIO_CONTENT_IMPORT_ERROR_TITLE}}",
				msg: "{{i18n PLUGINS_CONTENTIO_CONTENT_IMPORT_ERROR_SAME_CHAR}}",
				buttons: Ext.Msg.OK,
				icon: Ext.Msg.ERROR
			});
		}
		else if (error == 'no-header')
		{
			Ametys.Msg.show({
				title: "{{i18n PLUGINS_CONTENTIO_CONTENT_IMPORT_ERROR_TITLE}}",
				msg: "{{i18n PLUGINS_CONTENTIO_CONTENT_IMPORT_ERROR_NO_HEADER}}",
				buttons: Ext.Msg.OK,
				icon: Ext.Msg.ERROR
			});
		}
        else
        {
			Ametys.Msg.show({
				title: "{{i18n PLUGINS_CONTENTIO_CONTENT_IMPORT_ERROR_TITLE}}",
				msg: "{{i18n PLUGINS_CONTENTIO_CONTENT_IMPORT_ERROR_TEXT}}",
                msg: Ext.String.format("{{i18n PLUGINS_CONTENTIO_CONTENT_IMPORT_ERROR_TEXT}}", config.fileName),
				buttons: Ext.Msg.OK,
				icon: Ext.Msg.ERROR
			});
        }
    },
    
    /**
     * Handle the cancel button by hiding the dialog box.
     * @private
     */
    _cancel: function()
    {
        this._box.hide();
    }
    
});