/*
 *  Copyright 2022 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 is a singleton to handle actions on signup invitations
 */
Ext.define('Ametys.plugins.web.tempusers.InvitationActions', {
    singleton: true, 
    
    /**
     * Open a dialog box to send an invitation to signup
     * @param {Ametys.ribbon.element.ui.ButtonController} controller The controller calling this function
     */
    sendInvitation: function(controller)
    {
        if (!this._sendInvitationDialog)
        {
            this._sendInvitationDialog = this._sendInvitationDialogBox(controller, controller.getInitialConfig());
        }
        
        var form = this._sendInvitationDialog.items.getAt(0).getForm();
        form.reset();
        form.findField('userDirectory').setValue(controller.getInitialConfig().defaultUserDirectory);
        
        this._sendInvitationDialog.show();
    },
    
    /**
     * @private
     */
    _sendInvitationDialogBox: function(controller, config)
    {
        var formPanel = Ext.create('Ext.form.Panel', {
            border: false,
            
            scrollable: false,
            
            defaults: {
                cls: 'ametys',
                labelSeparator: '',
                labelAlign: 'top',
                anchor: "100%",
                msgTarget: 'side'
            },
            items: [
                {
                    xtype: 'component',
                    html: "{{i18n PLUGINS_WEB_USERS_SEND_INVITATION_DIALOG_HINT}}",
                    cls: 'text',
                    style: {
                        marginBottom: '10px'
                    }
                },
                {
                    xtype: 'edition.userdirectory',
                    itemId: 'userDirectory',
                    name: 'userDirectory',
                    fieldLabel: "* {{i18n PLUGINS_WEB_USERS_SEND_INVITATION_DIALOG_USER_DIRECTORY_LABEL}}",
                    ametysDescription: "{{i18n PLUGINS_WEB_USERS_SEND_INVITATION_DIALOG_USER_DIRECTORY_DESC}}",
                    allowBlank: false,
                    onlyModifiable: true,
                    userPopulationOnly: config.userPopulationOnly || false
                },
                {
                    xtype: 'textfield',
                    itemId: 'email',
                    name: 'email',      
                    fieldLabel: "* {{i18n PLUGINS_WEB_USERS_SEND_INVITATION_DIALOG_EMAIL_LABEL}}",
                    ametysDescription: "{{i18n PLUGINS_WEB_USERS_SEND_INVITATION_DIALOG_EMAIL_DESC}}",
                    allowBlank: false,
                    regex: new RegExp('^.+@.+$'),
                    regexText: "{{i18n plugin.core:PLUGINS_CORE_REGEXP_INVALID_MAIL}}"
                },
                {
                    xtype: 'textfield',
                    itemId: 'lastname',
                    name: 'lastname',
                    fieldLabel: "{{i18n PLUGINS_WEB_USERS_SEND_INVITATION_DIALOG_LASTNAME_LABEL}}",
                    ametysDescription: "{{i18n PLUGINS_WEB_USERS_SEND_INVITATION_DIALOG_LASTNAME_DESC}}"
                },
                {
                    xtype: 'textfield',
                    itemId: 'firstname',
                    name: 'firstname',
                    fieldLabel: "{{i18n PLUGINS_WEB_USERS_SEND_INVITATION_DIALOG_FIRSTNAME_LABEL}}",
                    ametysDescription: "{{i18n PLUGINS_WEB_USERS_SEND_INVITATION_DIALOG_FIRSTNAME_DESC}}"
                }
            ]
        });
        
        return Ext.create('Ametys.window.DialogBox', {
            title: "{{i18n PLUGINS_WEB_USERS_SEND_INVITATION_DIALOG_TITLE}}",
            iconCls: 'ametysicon-desktop-envelope-invitation',
            layout: {
                type: 'vbox',
                align : 'stretch',
                pack  : 'start'
            },
            width: 470,
            
            items: [formPanel],
            
            buttons: [{
                text: "{{i18n PLUGINS_WEB_USERS_SEND_INVITATION_DIALOG_OK}}",
                handler: Ext.bind(this._ok, this, [controller], false),
                scope: this
            }, {
                text: "{{i18n PLUGINS_WEB_USERS_SEND_INVITATION_DIALOG_CANCEL}}",
                handler: this._cancel,
                scope: this
            }]
        });
    },
    
    /**
     * @private
     */
    _ok: function(controller)
    {
        var form = this._sendInvitationDialog.items.getAt(0).getForm();
        if (form.isValid())
        {
	        var values = form.getValues();
            
            controller.serverCall('sendInvitation', [Ametys.getAppParameter("siteName"), values.userDirectory, values.email, values.lastname, values.firstname], Ext.bind(this._sendCb, this), {
                errorMessage: "{{i18n PLUGINS_WEB_USERS_SEND_INVITATION_ERROR_MSG}}",
                waitMessage: true
            });
        }
    },
    
    /**
     * @private
     */
    _sendCb: function(result)
    {
        if (!result.success)
        {
            var msg = "{{i18n PLUGINS_WEB_USERS_SEND_INVITATION_ERROR_MSG}}";
            msg += result.message || "{{i18n PLUGINS_WEB_USERS_SEND_INVITATION_ERROR_UNKNOWN}}";
            
            Ametys.Msg.show({
	            title: "{{i18n PLUGINS_WEB_USERS_SEND_INVITATION_ERROR_TITLE}}",
	            msg: msg,
	            buttons: Ext.Msg.OK,
	            icon: Ext.MessageBox.ERROR
	        });
        }
        else
        {
            this._sendInvitationDialog.hide();
            
            Ametys.Msg.show({
                title: "{{i18n PLUGINS_WEB_USERS_SEND_INVITATION_SUCCESS_TITLE}}",
                msg: "{{i18n PLUGINS_WEB_USERS_SEND_INVITATION_SUCCESS_MSG}}",
                buttons: Ext.Msg.OK,
                icon: Ext.MessageBox.INFO
            });
            
            Ext.create("Ametys.message.Message", {
                type: Ametys.message.Message.CREATED,
                targets: {
                    id: Ametys.message.MessageTarget.TEMP_USER,
                    parameters: {
                        email: result.email
                    }
                }
            });
        }
    },
    
    /**
     * @private
     */
    _cancel: function(button, event)
    {
        this._sendInvitationDialog.hide();
    },
    
    /**
     * Open a dialog box to import invitations from a CSV file
     * @param {Ametys.ribbon.element.ui.ButtonController} controller The controller calling this function
     */
    sendInvitationsFromCSV: function(controller)
    {
        if (!this._importDialog)
        {
            this._importDialog = this._createImportDialogBox(controller.getInitialConfig());
        }
        
        var form = this._importDialog.items.getAt(0).getForm();
        form.findField('userDirectory').setValue(controller.getInitialConfig().defaultUserDirectory);
        form.findField('resendInvitations').setValue(false);
        form.findField('file').reset();
        
        this._importDialog.show();
    },
    
    /**
     * @private
     */
    _createImportDialogBox: function(config)
    {
        var existingInvitationOpts = Ext.create('Ext.data.Store', {
		    fields: ['value', 'label'],
		    data : [
		        {"value": false, "label":"{{i18n PLUGINS_WEB_USERS_IMPORT_INVITATIONS_DIALOG_EXISTING_INVITATIONS_IGNORE}}"},
		        {"value": true, "label":"{{i18n PLUGINS_WEB_USERS_IMPORT_INVITATIONS_DIALOG_EXISTING_INVITATIONS_RESEND}}"}
		    ]
		});

        var formPanel = Ext.create('Ext.form.Panel', {
            border: false,
            
            scrollable: false,
            
            defaults: {
                cls: 'ametys',
                labelSeparator: '',
                labelAlign: 'top',
                anchor: "100%"
            },
            items: [
                {
                    xtype: 'component',
                    html: "{{i18n PLUGINS_WEB_USERS_IMPORT_INVITATIONS_DIALOG_HINT}}",
                    cls: 'text',
                    style: {
                        marginBottom: '10px'
                    }
                },
                {
                    xtype: 'fileuploadfield',
                    itemId: 'file',
                    name: 'file',
                    fieldLabel: "* {{i18n PLUGINS_WEB_USERS_IMPORT_INVITATIONS_DIALOG_FILE_LABEL}}",
                    ametysDescription: "{{i18n PLUGINS_WEB_USERS_IMPORT_INVITATIONS_DIALOG_FILE_DESC}}",
                    allowBlank: false,
                    emptyText: "{{i18n PLUGINS_WEB_USERS_IMPORT_INVITATIONS_DIALOG_FILE_EMPTY_TEXT}}",
                    buttonText: "{{i18n PLUGINS_WEB_USERS_IMPORT_INVITATIONS_DIALOG_FILE_BUTTON}}"
                },
                {
                    xtype: 'edition.userdirectory',
                    itemId: 'userDirectory',
                    name: 'userDirectory',
                    fieldLabel: "* {{i18n PLUGINS_WEB_USERS_IMPORT_INVITATIONS_DIALOG_USER_DIRECTORY_LABEL}}",
                    ametysDescription: "{{i18n PLUGINS_WEB_USERS_IMPORT_INVITATIONS_DIALOG_USER_DIRECTORY_DESC}}",
                    allowBlank: false,
                    onlyModifiable: true,
                    userPopulationOnly: config.userPopulationOnly || false
                },
                {
                    xtype: 'combobox',
                    itemId: 'resendInvitations',
                    name: 'resendInvitations',
                    store: existingInvitationOpts,
				    queryMode: 'local',
				    displayField: 'label',
				    valueField: 'value',
                    allowBlank: false,
                    fieldLabel: "* {{i18n PLUGINS_WEB_USERS_IMPORT_INVITATIONS_DIALOG_EXISTING_INVITATIONS_LABEL}}",
                    ametysDescription: "{{i18n PLUGINS_WEB_USERS_IMPORT_INVITATIONS_DIALOG_EXISTING_INVITATIONS_DESC}}"
                }
            ]
        });
        
        return Ext.create('Ametys.window.DialogBox', {
            title: "{{i18n PLUGINS_WEB_USERS_IMPORT_INVITATIONS_DIALOG_TITLE}}",
            iconCls: 'ametysicon-desktop-envelope-invitation',
            layout: {
                type: 'vbox',
                align : 'stretch',
                pack  : 'start'
            },
            width: 500,
            
            items: [formPanel],
            
            buttons: [{
                text: "{{i18n PLUGINS_WEB_USERS_IMPORT_INVITATIONS_DIALOG_OK}}",
                handler: this._validateImport,
                scope: this
            }, {
                text: "{{i18n PLUGINS_WEB_USERS_IMPORT_INVITATIONS_DIALOG_CANCEL}}",
                handler: this._cancelImport,
                scope: this
            }]
        });
    },
    
    /**
     * @private
     */
    _validateImport: function(button, event)
    {
        var form = this._importDialog.items.getAt(0).getForm();
        if (form.isValid())
        {
            Ametys.Msg.confirm("{{i18n PLUGINS_WEB_USERS_IMPORT_INVITATIONS_CONFIRM_TITLE}}",
                    "{{i18n PLUGINS_WEB_USERS_IMPORT_INVITATIONS_CONFIRM}}",
                    function(answer) {
                        if (answer == 'yes')
                        {
                            this._doImport(form);
                        }
                    },
                    this
            );
        }
    },
    
    /**
     * @private
     */
    _doImport: function(form)
    {
        var formValues = form.getFieldValues();
        var resendInvitations = formValues["resendInvitations"] == "true";
        var parameters = [formValues["userDirectory"], resendInvitations, form.findField('file').getFiles()[0]];
        
        Ametys.data.ServerComm.callMethod({
            role: 'org.ametys.web.usermanagement.ImportInvitations', 
            methodName: 'doImport',
            parameters: parameters,
            priority: Ametys.data.ServerComm.PRIORITY_LONG_REQUEST,
            callback: {
                    handler: this._doImportCb,
                    scope: this,
                },
            errorMessage: "{{i18n PLUGINS_WEB_USERS_SEND_INVITATION_ERROR_MSG}}",
            progressMessage: {
                title: "{{i18n PLUGINS_WEB_USERS_IMPORT_INVITATIONS_WAIT_TITLE}}",
                msg: "{{i18n PLUGINS_WEB_USERS_IMPORT_INVITATIONS_WAIT_MSG}}"
            }
        });
    },
    
    /**
     * @private
     * This function is called after the resources have tried to be imported
     * @param {Object} result The results
     */
    _doImportCb: function(result)
    {
        if (result.success)
        {
            this._success(result);
        }
        else
        {
            this._failure(result);
        }
    },
    
    /**
     * @private
     */
    _success: function(result)
    {
        this._importDialog.hide();
    },
    
    
    /**
     * @private
     */
    _failure: function(result)
    {
        var message = '';
        var error = result.error;
        
        if (error == 'invalid-extension')
        {
            message = "{{i18n PLUGINS_WEB_USERS_IMPORT_INVITATIONS_ERROR_INVALID_FILE}}";
        }
        else if (error == 'rejected-file')
        {
            message = "{{i18n PLUGINS_WEB_USERS_IMPORT_INVITATIONS_ERROR_REJECTED_FILE}}";
        }
        else if (error == 'file-error')
        {
            message = "{{i18n PLUGINS_WEB_USERS_IMPORT_INVITATIONS_ERROR_FILE_ERROR}}";
        }
        else if (error == 'schedule-error')
        {
            message = "{{i18n PLUGINS_WEB_USERS_IMPORT_INVITATIONS_ERROR_SCHEDULE_ERROR}}";
        }
        else
        {
            message = "{{i18n PLUGINS_WEB_USERS_IMPORT_INVITATIONS_ERROR}}";
        }
        
        Ametys.Msg.show({
            title: "{{i18n PLUGINS_WEB_USERS_IMPORT_INVITATIONS_ERROR_TITLE}}",
            msg: message,
            buttons: Ext.Msg.OK,
            icon: Ext.MessageBox.ERROR
        });
    },
    
    /**
     * @private
     */
    _cancelImport: function(button, event)
    {
        this._importDialog.hide();
    },
    
    /**
     * Resend an existing invitation to signup
     * @param {Ametys.ribbon.element.ui.ButtonController} controller The controller calling this function
     */
    resendInvitation: function(controller)
    {
        var targets = controller.getMatchingTargets();
        if (targets.length == 0)
        {
            return;
        }
        
        Ametys.Msg.confirm("{{i18n PLUGINS_WEB_USERS_RESEND_INVITATION_CONFIRM_TITLE}}",
                    "{{i18n PLUGINS_WEB_USERS_RESEND_INVITATION_CONFIRM_MSG}}",
                    function(answer) {
                        if (answer == 'yes')
                        {
                            this._doResendInvitation(targets[0], controller);
                        }
                    },
                    this
            );
    },
    
    /**
     * @private
     */
    _doResendInvitation: function(target, controller)
    {
        var params = target.getParameters();
        
        controller.serverCall('resendInvitation', [Ametys.getAppParameter("siteName"), params.email, params.population, params.userDirectory], Ext.bind(this._resendInvitationCb, this), {
                errorMessage: "{{i18n PLUGINS_WEB_USERS_RESEND_INVITATION_ERROR_MSG}}",
                waitMessage: true
            });
    },
    
    /**
     * @private
     * Callback function invoke after resend of invitation
     * @param {Object} result the result map
     */
    _resendInvitationCb: function(result)
    {
        if (!result.success)
        {
            var msg = "{{i18n PLUGINS_WEB_USERS_RESEND_INVITATION_ERROR_MSG}}";
            msg += result.message || "{{i18n PLUGINS_WEB_USERS_RESEND_INVITATION_ERROR_UNKNOWN}}";
            
            Ametys.Msg.show({
                title: "{{i18n PLUGINS_WEB_USERS_RESEND_INVITATION_ERROR_TITLE}}",
                msg: msg,
                buttons: Ext.Msg.OK,
                icon: Ext.MessageBox.ERROR
            });
        }
        else
        {
            Ametys.Msg.show({
                title: "{{i18n PLUGINS_WEB_USERS_RESEND_INVITATION_SUCCESS_TITLE}}",
                msg: "{{i18n PLUGINS_WEB_USERS_RESEND_INVITATION_SUCCESS_MSG}}",
                buttons: Ext.Msg.OK,
                icon: Ext.MessageBox.INFO
            });
            
            Ametys.plugins.web.tempusers.TempUsersDAO.localUpdate(result.email, {
                subscriptionDate: result.subscriptionDate,
                expired: false
            });
            
            Ext.create('Ametys.message.Message', {
                type: Ametys.message.Message.MODIFIED,
                targets: [{
                    id: Ametys.message.MessageTarget.TEMP_USER,
                    parameters: {
                        email: result.email
                    }
                }]
            });
        }
    },
    
    /**
     * Resend an existing invitation to signup
     * @param {Ametys.ribbon.element.ui.ButtonController} controller The controller calling this function
     */
    removeInvitation: function(controller)
    {
        var targets = controller.getMatchingTargets();
        if (targets.length == 0)
        {
            return;
        }
        
        var emails = controller.getAllRightEmails();
        
        var confirmMsg = Ext.String.format("{{i18n PLUGINS_WEB_USERS_REMOVE_INVITATION_CONFIRM_MSG}}", emails.join(", "));
        
        Ametys.Msg.confirm("{{i18n PLUGINS_WEB_USERS_REMOVE_INVITATION_CONFIRM_TITLE}}",
                   confirmMsg,
                    function(answer) {
                        if (answer == 'yes')
                        {
                            this._doRemoveInvitation(targets, controller);
                        }
                    },
                    this
            );
        
    },
    
    /**
     * @private
     */
    _doRemoveInvitation: function (targets, controller)
    {
        var emails = controller.getAllRightEmails();
        
        controller.serverCall('removeInvitation', [Ametys.getAppParameter("siteName"), emails], Ext.bind(this._removeInvitationCb, this, [targets], 1), {
                errorMessage: "{{i18n PLUGINS_WEB_USERS_REMOVE_INVITATION_ERROR_MSG}}",
                waitMessage: true
            });
    },
    
    /**
     * @private
     * Callback function invoke after resend of invitation
     * @param {Object} result the result map
     * @param {Ametys.message.MessageTarget} target the initial targets
     */
    _removeInvitationCb: function(result, initialTargets)
    {
        if (!result.success)
        {
            var msg = "{{i18n PLUGINS_WEB_USERS_REMOVE_INVITATION_ERROR_MSG}}";
            msg += result.message || "{{i18n PLUGINS_WEB_USERS_REMOVE_INVITATION_ERROR_UNKNOWN}}";
            
            Ametys.Msg.show({
                title: "{{i18n PLUGINS_WEB_USERS_REMOVE_INVITATION_ERROR_TITLE}}",
                msg: msg,
                buttons: Ext.Msg.OK,
                icon: Ext.MessageBox.ERROR
            });
        }
        else
        {
            var deletedInvitations = result['deleted-invitations'];
            
            var deletedTargets = Ext.Array.filter (initialTargets, function (target) {
	            return Ext.Array.contains(deletedInvitations, target.getParameters().email);
	        });
        
            if (deletedTargets.length > 0)
            {
                Ext.create('Ametys.message.Message', {
	                type: Ametys.message.Message.DELETED,
	                targets: deletedTargets
	            });
            }
            
            var noRightInvitations = result['noright-invitations'];
            var noInvitations = result['no-invitations'];
            
            var errorMsg = "";
            if (noRightInvitations.length > 0)
            {
                errorMsg += Ext.String.format("{{i18n PLUGINS_WEB_USERS_REMOVE_INVITATION_ERROR_NORIGHT}}", noRightInvitations.join(", "));
            }
            if (noInvitations.length > 0)
            {
                errorMsg += Ext.String.format("{{i18n PLUGINS_WEB_USERS_REMOVE_INVITATION_ERROR_UNREMOVABLE_SIGNUP_REQUEST}}", noInvitations.join(", "));
            }
            
            if (errorMsg != '')
            {
                Ametys.Msg.show({
	                title: "{{i18n PLUGINS_WEB_USERS_REMOVE_INVITATION_ERROR_TITLE}}",
	                msg: errorMsg,
	                buttons: Ext.Msg.OK,
	                icon: Ext.MessageBox.ERROR
	            });
            }
        }
    }
    
});