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

/**
 * Helper to handle double MCC templates
 */
Ext.define('Ametys.plugins.odf.pilotage.helper.DoubleMCCTemplatesHelper', {
    singleton: true,
    
    /**
     * Show MCC sessions templates grid to handle them
     * @param {Ext.grid.Panel[]} grids The two MCC grid panels
     * @param {String} regime The regime
     * @param {Boolean} canApplyOnGrid1 True if templates can be applied on grid 1
     * @param {Boolean} canApplyOnGrid2 True if templates can be applied on grid 2
     */
    handleMCCSessionsTemplates: function(grids, regime, canApplyOnGrid1, canApplyOnGrid2)
    {
        this._mccGrids = grids;
        this._regime = regime;
        this._canApplyOnGrid1 = canApplyOnGrid1;
        this._canApplyOnGrid2 = canApplyOnGrid2;
        this._templatesBox = this._templatesBox || this._createTemplatesDialogBox();
        this._templatesStore.load({
            callback: Ext.bind(function() {
                if (this._templatesStore.getCount() > 0)
                {
                    this._templatesGrid.getView().unmask();
                }
                else
                {
                    this._templatesGrid.getView().mask("{{i18n plugin.odf-pilotage:PLUGINS_ODF_PILOTAGE_MCC_SESSIONS_GRID_NO_TEMPLATE}}", 'ametys-mask-unloading');
                }
                
                this._templatesBox.down('#delete').disable();
                this._templatesBox.down('#apply').disable();
                this._templatesBox.show();
            }, this)
        });
    },
    
    /**
     * Create the dialog box with MCC sessions templates to handle them
     * @private
     */
    _createTemplatesDialogBox: function()
    {
        this._templatesGrid = this._createTemplatesGrid();
        return Ext.create('Ametys.window.DialogBox', {
            title : "{{i18n plugin.odf-pilotage:PLUGINS_ODF_PILOTAGE_MCC_SESSIONS_DIALOG_BOX_TITLE}}",
            iconCls : "odficon-course",
            width: 400,
            freezeHeight: true,
            
            layout: {
                type: 'anchor',
            },
            defaults: {
                cls: 'ametys',
                labelAlign: 'right',
                labelSeparator: '',
                labelWidth: 130,
                anchor: '100%'
            },
            
            items: [this._templatesGrid],
            
            selectDefaultFocus: true,
            closeAction: 'hide',
            referenceHolder: true,
            defaultButton: 'apply',
            
            buttons : [
                {
                    text: "{{i18n plugin.odf-pilotage:PLUGINS_ODF_PILOTAGE_MCC_SESSIONS_DIALOG_BOX_DELETE}}",
                    id: "delete",
                    disabled: true,
                    handler: this._deleteTemplate,
                    scope: this
                },
                { xtype: 'tbspacer', flex: 1 },
                {
                    reference: 'apply',
                    text: "{{i18n plugin.odf-pilotage:PLUGINS_ODF_PILOTAGE_MCC_SESSIONS_DIALOG_BOX_APPLY}}",
                    id: "apply",
                    tooltip: "{{i18n plugin.odf-pilotage:PLUGINS_ODF_PILOTAGE_MCC_SESSIONS_APPLY_TOOLTIP}}",
                    disabled: true,
                    handler: this._applyTemplate,
                    scope: this
                }, 
                {
                    text: "{{i18n plugin.odf-pilotage:PLUGINS_ODF_PILOTAGE_MCC_SESSIONS_DIALOG_BOX_CANCEL}}",
                    handler: function() {this._templatesBox.close()},
                    scope: this
                }
            ]
        });
    },
    
    /**
     * Create the grid with MCC sessions templates
     * @private
     */
    _createTemplatesGrid: function()
    {
        var cfg = {
            proxy: {
                type: 'ametys',
                role: 'org.ametys.plugins.odfpilotage.helper.PilotageMCCSessionsTemplateHelper',
                methodName: 'getUserMCCSessionsTemplates',
                parameters: [],
                reader: {
                    type: 'json',
                    rootProperty: 'templates'
                }
            },
            sorters: [{property: 'title', direction:'ASC'}],
            fields: [{name: 'title', mapping: 'title'}]
        }
        
        this._templatesStore = Ext.create('Ext.data.Store', cfg);
        
        return Ext.create('Ext.grid.Panel', {
            store: this._templatesStore,
            columns: [{ 
                text: '{{i18n plugin.odf-pilotage:PLUGINS_ODF_PILOTAGE_MCC_SESSIONS_GRID_COLUMN_TITLE}}', 
                dataIndex: 'title', 
                flex: 1 , 
                editor: {
                    xtype: 'textfield',
                    allowBlank: false,
                    selectOnFocus: true
                } 
            }],
            listeners: {
                'select': function() {
                    if (this._canApplyOnGrid1 || this._canApplyOnGrid2)
                    {
                        this._templatesBox.down("#apply").enable();
                    }
                    this._templatesBox.down("#delete").enable();
                },
                scope: this
            },
            columnLines: true,
            forceFit: true,
            selModel: 'cellmodel',
            plugins: {
                ptype: 'cellediting',
                clicksToEdit: 1,
                editAfterSelect: true,
                listeners: {
                    'edit': this._renameTemplate,
                    scope: this
                }
            },
            minHeight: 200,
            maxHeight: 400
        });
    },
    
    /**
     * Rename template after cell editing
     * @param {Ext.grid.plugin.CellEditing} editor The cell editor
     * @param {Object} context An editing context
     * @private
     */
    _renameTemplate: function(editor, context)
    {
        var record = context.record,
            newName = context.value,
            oldName = context.originalValue;
        
        if (newName != oldName)
        {
            let items = this._templatesStore.queryRecordsBy(function(r) {return r.get("title") == newName })
            if (items.length > 1)
            {
                record.set('title', oldName, {commit: true});
            }
            else
            {
                Ametys.data.ServerComm.callMethod({
                    role: "org.ametys.plugins.odfpilotage.helper.PilotageMCCSessionsTemplateHelper",
                    methodName: "renameMCCSessionsTemplate",
                    parameters: [oldName, newName],
                    callback: {
                        handler: Ext.bind(this._renameTemplateCB, this, [record, oldName], 1),
                        scope: this
                    },
                    errorMessage: true
                }); 
            }
        }
    },
    
    /**
     * Rename template callback
     * @param {Object} response The response
     * @param {Object} record The edited record
     * @param {String} oldName The template old name
     * @private
     */
    _renameTemplateCB: function(response, record, oldName)
    {
        if (this._handleError(response, "{{i18n plugin.odf-pilotage:PLUGINS_ODF_PILOTAGE_MCC_SESSIONS_ERROR_RENAME_ERROR}}"))
        {
            // edit failed
            record.set('title', oldName);
        }
        record.commit();
    },
    
    /**
     * Delete selected template
     * @private
     */
    _deleteTemplate: function()
    {
        let templateName = this._templatesGrid.getSelection()[0].get("title");
        Ametys.Msg.confirm("{{i18n plugin.odf-pilotage:PLUGINS_ODF_PILOTAGE_MCC_SESSIONS_DELETE_CONFIRM_TITLE}}",
            Ext.String.format("{{i18n plugin.odf-pilotage:PLUGINS_ODF_PILOTAGE_MCC_SESSIONS_DELETE_CONFIRM_MSG}}", "<strong>" + templateName + "</strong>"),
            function(btn) {
                if (btn == 'yes')
                {
                    Ametys.data.ServerComm.callMethod({
                        role: "org.ametys.plugins.odfpilotage.helper.PilotageMCCSessionsTemplateHelper",
                        methodName: "deleteMCCSessionsTemplate",
                        parameters: [templateName],
                        callback: {
                            handler: Ext.bind(this._deleteTemplateCB, this, [templateName], 1),
                            scope: this
                        },
                        errorMessage: true
                    }); 
                }
            },
            this
        );
    },
    
    /**
     * Delete template callback
     * @param {Object} response The response
     * @param {String} templateName The template name
     * @private
     */
    _deleteTemplateCB: function(response, templateName)
    {
        if (!this._handleError(response, "{{i18n plugin.odf-pilotage:PLUGINS_ODF_PILOTAGE_MCC_SESSIONS_ERROR_DELETE_ERROR}}"))
        {
            let recordIndex = this._templatesStore.findBy(function(r) { return r.get("title") == templateName});
            this._templatesStore.removeAt(recordIndex)
            
            this._templatesBox.down('#delete').disable();
            this._templatesBox.down('#apply').disable();
            
            if (this._templatesStore.getCount() == 0)
            {
                this._templatesGrid.getView().mask("{{i18n plugin.odf-pilotage:PLUGINS_ODF_PILOTAGE_MCC_SESSIONS_GRID_NO_TEMPLATE}}", 'ametys-mask-unloading');
            }
        }
    },
    
    /**
     * Apply MCC session of the selected template
     * @private
     */
    _applyTemplate: function()
    {
        let templateName = this._templatesGrid.getSelection()[0].get("title");
        Ametys.data.ServerComm.callMethod({
            role: "org.ametys.plugins.odfpilotage.helper.PilotageMCCSessionsTemplateHelper",
            methodName: "getMCCSessionsTemplate",
            parameters: [templateName],
            callback: {
                handler: this._applyTemplateCB,
                scope: this
            },
            errorMessage: true
        }); 
    },
    
    /**
     * Callback after applying MCC session of the template
     * @param {Object} response The response
     * @private
     */
    _applyTemplateCB: function(response)
    {
        if (!this._handleError(response, "{{i18n plugin.odf-pilotage:PLUGINS_ODF_PILOTAGE_MCC_SESSIONS_ERROR_APPLY_ERROR}}"))
        {
            let regime = this._regime;
            let sessions = response.sessions;
            for (let i in sessions)
            {
                if (i == 0 && this._canApplyOnGrid1 || i == 1 && this._canApplyOnGrid2)
                {
                    let session = sessions[i];
                    if (session != null)
                    {
                        let gridStore = this._mccGrids[i].getStore();
                        for (let data of session)
                        {
                            let newRecord = gridStore.getModel().create();
                            gridStore.add(newRecord);
                            if (data.modalite)
                            {
                                Ametys.plugins.odfpilotage.widget.MccModalite._getCompatibleRegimes(data.modalite, function(compatibleRegimes) {
                                    if (regime && compatibleRegimes.length && compatibleRegimes.indexOf(regime) == -1)
                                    {
                                        delete data.modalite;
                                    }
                                    delete data.id;
                                    newRecord.set(data);
                                });
                            }
                            else
                            {
                                delete data.id;
                                newRecord.set(data);    
                            }
                        }
                    }
                }
            }
            
            this._templatesBox.close();
        }
    },
    
    /**
     * Create a MCC sessions templates
     * @param {Ext.grid.Panel[]} grids The two MCC grid panels
     */
    createTemplate: function(grids)
    {
        this._mccGrids = grids;

        Ametys.data.ServerComm.callMethod({
            role: "org.ametys.plugins.odfpilotage.helper.PilotageMCCSessionsTemplateHelper",
            methodName: "getUserMCCSessionsTemplates",
            parameters: [{}],
            callback: {
                handler: this._getTemplatesCB,
                scope: this
            },
            errorMessage: true
        }); 
    },
    
    /**
     * Callback after getting the templates
     * @param {Object} response the server response
     * @private
     */
    _getTemplatesCB: function(response)
    {
        this._templateNames = response.templates.map(t => t.title);
        
        this._templateCreationBox = this._templateCreationBox || this._createTemplateCreationDialogBox();
        this._templateCreationBox.down('#template-name').setValue(null);
        this._templateCreationBox.down('#template-name').clearInvalid(); 
        this._templateCreationBox.show();
    },
    
    /**
     * Create the dialog box to create a MCC sessions template
     * @private
     */
    _createTemplateCreationDialogBox: function()
    {
        return Ext.create('Ametys.window.DialogBox', {
            title : "{{i18n plugin.odf-pilotage:PLUGINS_ODF_PILOTAGE_MCC_SESSIONS_DIALOG_BOX_CREATE_TITLE}}",
            iconCls : "odficon-course",
            width: 400,
            layout: 'anchor',
            
            items: [{
                anchor: '100%',
                labelSeparator: '',
                labelAlign: 'top',
                cls: 'ametys',
                xtype: "textfield",
                id: "template-name",
                fieldLabel: "{{i18n plugin.odf-pilotage:PLUGINS_ODF_PILOTAGE_MCC_SESSIONS_DIALOG_BOX_CREATE_FIELD_TITLE_LABEL}} *",
                ametysDescription: "{{i18n plugin.odf-pilotage:PLUGINS_ODF_PILOTAGE_MCC_SESSIONS_DIALOG_BOX_CREATE_FIELD_TITLE_DESC}}",
                allowBlank: false,
            }],
            
            defaultFocus: 'template-name',
            selectDefaultFocus: true,
            closeAction: 'hide',
            
            referenceHolder: true,
            defaultButton: 'validate',
            
            buttons : [
                {
                    reference: 'validate',
                    text: "{{i18n plugin.odf-pilotage:PLUGINS_ODF_PILOTAGE_MCC_SESSIONS_DIALOG_BOX_CREATE_OK}}",
                    handler: this._createTemplate,
                    scope: this
                }, {
                    text: "{{i18n plugin.odf-pilotage:PLUGINS_ODF_PILOTAGE_MCC_SESSIONS_DIALOG_BOX_CREATE_CANCEL}}",
                    handler: function() {this._templateCreationBox.close()},
                    scope: this
            }]
        });
    },
    
    /**
     * Create a MCC sessions template
     * @private
     */
    _createTemplate: function()
    {
        var templateName = this._templateCreationBox.down('#template-name').getValue();
        if (templateName == "")
        {
            return;
        }
        
        var sessions = this._mccGrids.map(grid => this._gridToValues(grid));
        if (this._templateNames.indexOf(templateName) != -1)
        {
            Ametys.Msg.confirm("{{i18n plugin.odf-pilotage:PLUGINS_ODF_PILOTAGE_MCC_SESSIONS_ERROR_RENAME_ALREADY_EXIST_TITLE}}",
            Ext.String.format("{{i18n plugin.odf-pilotage:PLUGINS_ODF_PILOTAGE_MCC_SESSIONS_ERROR_RENAME_ALREADY_EXIST_MSG}}", "<strong>" + templateName + "</strong>"),
            function(btn) {
                if (btn == 'yes')
                {
                    this._doCreateTemplate(templateName, sessions);
                }
            },
            this
        );
        }
        else
        {
            this._doCreateTemplate(templateName, sessions);
        }
    },
    
    /**
     * @private
     * Convert the data of the given grid into repeater values
     * @param {Ext.grid.Panel} grid The current grid
     * @return {Object[]} The array of data of the grid
     */
    _gridToValues: function(grid)
    {
        var entriesValues = [];
        
        var gridStore = grid.getStore();
        for (var index = 0; index < gridStore.getCount(); index++)
        {
            var record = gridStore.getAt(index);
            var data = record.getData();
            entriesValues.push(data);
        }
        
        return entriesValues;
    },
    
    /**
     * Do create MCC sessions template
     * @param {String} templateName the template name
     * @param {Object} sessions the sessions
     * @private
     */
    _doCreateTemplate: function(templateName, sessions)
    {
        Ametys.data.ServerComm.callMethod({
            role: "org.ametys.plugins.odfpilotage.helper.PilotageMCCSessionsTemplateHelper",
            methodName: "createMCCSessionsTemplate",
            parameters: [templateName, sessions],
            callback: {
                handler: Ext.bind(this._doCreateTemplateCB, this, [templateName], 1),
                scope: this
            },
            errorMessage: true
        });   
    },
    
    /**
     * Create a MCC sessions template callback
     * @param {Object} response the server response
     * @private
     */
    _doCreateTemplateCB: function(response, templateName)
    {
        if (!this._handleError(response, "{{i18n plugin.odf-pilotage:PLUGINS_ODF_PILOTAGE_MCC_SESSIONS_ERROR_CREATE_ERROR}}"))
        {
            this._templateCreationBox.close();
            
            Ametys.Msg.show({
                title: "{{i18n plugin.odf-pilotage:PLUGINS_ODF_PILOTAGE_MCC_SESSIONS_CREATE_TITLE}}",
                msg: Ext.String.format("{{i18n plugin.odf-pilotage:PLUGINS_ODF_PILOTAGE_MCC_SESSIONS_CREATE_MSG}}", "<strong>" + templateName + "</strong>"),
                buttons: Ext.Msg.OK,
                icon: Ext.Msg.INFO
            });
        }
    },
    
    /**
     * @private
     * Handle error of response
     * @param {Object} response the server response
     * @param {String} errorMsg The error message
     */
    _handleError: function(response, errorMsg)
    {
        var hasError = false;
        if (response.error)
        {
            Ametys.Msg.show({
                title: "{{i18n plugin.odf-pilotage:PLUGINS_ODF_PILOTAGE_MCC_SESSIONS_ERROR_TITLE}}",
                msg: errorMsg,
                buttons: Ext.Msg.OK,
                icon: Ext.Msg.ERROR
            });
        }
        return hasError;
    }
});