/*
 *  Copyright 2023 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.
 */
 
 /**
  * Actions on workflow step and actions's function
  */
 Ext.define('Ametys.plugins.workflow.actions.WorkflowFunctionAction', {
    singleton: true,
    
    /**
    * @private
    * @property {String} _mode 'new' or 'edit' 
    */
    
    /**
    * @private
    * @property {String} _workflowName id of the workflow
    */
    
    /**
    * @private
    * @property {String} _stepId id of current step parent
    */
    
    /**
    * @private
    * @property {String} _actionId id of current action parent, can be null
    */
    
    /**
    * @private
    * @property {String} _type pre if the function is a prefunction, post if its a postfunction
    */
   
    /**
    * @private
    * @property {String} _id id of the enhanced function
    */
    
    /**
    * @private
    * @property {Number} _index index of function in the workflow element's function list
    */
    
    /**
    * @private
    * @property {Ametys.window.DialogBox} _functionBox the dialog box for functions
    */
    
    /**
    * @private
    * @property {Ametys.form.ConfigurableFormPanel} _formParams the configurable form for function's other arguments
    */
    
     /**
     * Add a new function
     * @param {Ametys.ribbon.element.ui.ButtonController} controller The controller calling this function
     */
    addFunction: function(controller)
    {
        var target = Ametys.message.MessageTargetHelper.findTarget(controller.getMatchingTargets());
        var stepTarget = target ? target.getSubtarget(function(target){return target.getId() == Ametys.message.MessageTarget.WORKFLOW_STEP}) : null;
        if (!stepTarget)
        {
            return; 
        }
        var actionTarget = target.getSubtarget(function(target){return target.getId() == Ametys.message.MessageTarget.WORKFLOW_ACTION});
        
        this._workflowName = target.getParameters().id;
        this._stepId = stepTarget.getParameters().id;
        this._actionId = actionTarget != null ? actionTarget.getParameters().id : null;
        this._mode = "new";
        
        if (!this._formParams)
        {
            Ametys.plugins.workflow.dao.WorkflowFunctionDAO.getFunctionsModel([], Ext.bind(this._configureCB, this)); 
        }
        else
        {
            this._formParams.reset();
            this._functionBox.setTitle("{{i18n PLUGINS_WORKFLOW_ADD_FUNCTION_DIALOG_TITLE}}");
            this._functionBox.show();
        }
    },
     
     /**
     * @private 
     * Initialize the dialog box and configure the form params
     *  @param {Object} response the server's response
      * @param {Object} response.parameters.elements the fields to configure
      * @param {String} id the id of current function, is null in new mode
     * @returns {Ametys.window.DialogBox} the dialog box
     */
    _configureCB: function(response, id)
    {
        var cfpConfig = {
            hideDisabledFields: true,
            spacingCls: false,
            labelAlign: 'top',
            defaultFieldConfig: {
                cls: 'ametys',
                labelStyle: "font-weight:bold",
            },
        };
        
        this._formParams = Ext.create('Ametys.form.ConfigurableFormPanel', cfpConfig);
        
        this._functionBox =  Ext.create('Ametys.window.DialogBox', {
            title : this._mode == "new" ? "{{i18n PLUGINS_WORKFLOW_ADD_FUNCTION_DIALOG_TITLE}}" : "{{i18n PLUGINS_WORKFLOW_EDIT_FUNCTION_DIALOG_TITLE}}",
            iconCls: "ametysicon-desktop-school-tool-pot",
            
            layout: 'fit',
            items : [
                this._formParams
            ],
            
            maxHeight : Math.max(500, window.innerHeight * 0.8),
            width: 600,
            closeAction: 'hide',
            
            referenceHolder: true,
            defaultButton: 'validate',
            
            buttons : [
                {
                    reference: 'validate',
                    itemId:'validateFunction',
                    text: "{{i18n PLUGINS_WORKFLOW_CREATE_DIALOG_OK_BTN}}",
                    handler: Ext.bind(this._ok, this)
                },
                {
                    text: "{{i18n PLUGINS_WORKFLOW_CREATE_DIALOG_CANCEL_BTN}}",
                    handler: Ext.bind(this._hideDialogBox, this)
                }
            ]
        });
        
        this._formParams.configure(response.parameters.elements);
        
        if (this._mode == "new")
        {
            this._formParams.setValues(); // setValues must always be called for configurable form panel in order to complete its initialization
            this._functionBox.show();
        }
        else
        {
            Ametys.plugins.workflow.dao.WorkflowFunctionDAO.getFunctionParametersValues([this._workflowName, parseInt(this._stepId), parseInt(this._actionId), this._type, id, parseInt(this._index)], Ext.bind(this._setValues, this)); 
        }
    },
    
    /**
     * @private
     * Send the changes to server
     */
    _ok: function ()
    {
        var paramValues = this._formParams.getJsonValues();
        var invalids = this._formParams.getInvalidFields();
        if (invalids.length)
        {
            return;
        }
        for (var argName in paramValues)
        {
            if (paramValues[argName] == "")
            {
                delete paramValues[argName];
            }
        }
        
        this._mode == "new"
            ? Ametys.plugins.workflow.dao.WorkflowFunctionDAO.addFunction([this._workflowName, parseInt(this._stepId), parseInt(this._actionId), paramValues], this._hideDialogBox, {scope: this})
            : Ametys.plugins.workflow.dao.WorkflowFunctionDAO.editFunction([this._workflowName, parseInt(this._stepId), parseInt(this._actionId), this._type, paramValues, parseInt(this._index)], this._hideDialogBox, {scope: this});
    },
    
    /**
     * @private
     * Hide the dialog box
     */
    _hideDialogBox: function ()
    {
        this._functionBox.hide();
    },
    
    /**
     * Edit a function
     * @param {Ametys.message.MessageTarget} target The function target
     */
    editFunction: function(target)
    {
        this._workflowName = target.getParameters().workflowId;
        this._stepId = target.getParameters().stepId;
        this._actionId = target.getParameters().actionId;
        this._id = target.getParameters().id;
        this._type = target.getParameters().type;
        this._index = target.getParameters().index;
        this._mode = "edit";
        if (!this._formParams)
        {
            Ametys.plugins.workflow.dao.WorkflowFunctionDAO.getFunctionsModel([], Ext.bind(this._configureCB, this, [this._id], 1)); 
        }
        else
        {
            Ametys.plugins.workflow.dao.WorkflowFunctionDAO.getFunctionParametersValues([this._workflowName, parseInt(this._stepId), parseInt(this._actionId), this._type, this._id, parseInt(this._index)], Ext.bind(this._setValues, this)); 
        }
        
     },
     
     /**
      * Set the function's current values in the dialog box fields
      * @param {Object} response the server's response
      * @param {Object} response.parametersValues the parameters fields current values
      * 
      */
     _setValues: function(response)
    {
        this._formParams.setValues({"values": response.parametersValues});
        this._functionBox.setTitle("{{i18n PLUGINS_WORKFLOW_EDIT_FUNCTION_DIALOG_TITLE}}");
        this._functionBox.show();
    },
    
    /**
     * Delete the function
     * @param {Ametys.message.MessageTarget} target The function target
     */
    deleteFunction: function(target)
    {
        var targetParameters = target.getParameters();
        this._id = targetParameters.id;
        this._workflowName = targetParameters.workflowId;
        this._stepId = targetParameters.stepId;
        this._actionId = targetParameters.actionId;
        this._type = targetParameters.type;
        this._index = targetParameters.index;
        
        Ametys.plugins.workflow.dao.WorkflowFunctionDAO.getFunctionDescription([this._workflowName, parseInt(this._stepId), parseInt(this._actionId), this._type, this._id, parseInt(this._index)], Ext.bind(this._deleteFunctionCB, this));
    },
    
    /**
      * @private
      * Callback of deleteFunction, send confirmation message for deletion
      * @param {Object} label function to remove's label
      */
    _deleteFunctionCB: function(label)
    {
        var msg = Ext.String.format("{{i18n PLUGINS_WORKFLOW_DELETE_FUNCTION_CONFIRM}}", label);
        
        Ametys.Msg.confirm("{{i18n PLUGINS_WORKFLOW_DELETE_FUNCTION_LABEL}}",
                msg,
                Ext.bind(this._doRemove, this),
                this
        );
    },
    
    /**
     * @private
     * Proceed to the function deletion
     * @param {String} btn The pressed button. Can only be 'yes'/'no'
     */
    _doRemove: function(btn)
    {
        if (btn == 'yes')
        {
            Ametys.plugins.workflow.dao.WorkflowFunctionDAO.deleteFunction([this._workflowName, parseInt(this._stepId), parseInt(this._actionId), this._type, this._id, parseInt(this._index)]); 
        }
    },
    
    /**
     * Move the function up in the callstack
     * @param {Ametys.ribbon.element.ui.ButtonController} controller The controller calling this function
     */
    moveUpFunction: function(controller)
    {
        var target = Ametys.message.MessageTargetHelper.findTarget(controller.getMatchingTargets());
        var functionTarget = target ? target.getSubtarget(function(target){return target.getId() == Ametys.message.MessageTarget.WORKFLOW_FUNCTION}) : null;
        if (!functionTarget)
        {
            return;
        }
        var targetParameters = functionTarget.getParameters(),
            workflowName = targetParameters.workflowId,
            stepId = targetParameters.stepId,
            actionId = targetParameters.actionId,
            type = targetParameters.type,
            index = targetParameters.index;
            
        Ametys.plugins.workflow.dao.WorkflowFunctionDAO.moveUp([workflowName, parseInt(stepId), parseInt(actionId), type, parseInt(index)]); 
    },
    
    /**
     * Move the function down in the callstack
     * @param {Ametys.ribbon.element.ui.ButtonController} controller The controller calling this function
     */
    moveDownFunction: function(controller)
    {
        var target = Ametys.message.MessageTargetHelper.findTarget(controller.getMatchingTargets());
        var functionTarget = target ? target.getSubtarget(function(target){return target.getId() == Ametys.message.MessageTarget.WORKFLOW_FUNCTION}) : null;
        if (!functionTarget)
        {
            return;
        }
        var targetParameters = functionTarget.getParameters(),
            workflowName = targetParameters.workflowId,
            stepId = targetParameters.stepId,
            actionId = targetParameters.actionId,
            type = targetParameters.type,
            index = targetParameters.index;
            
        Ametys.plugins.workflow.dao.WorkflowFunctionDAO.moveDown([workflowName, parseInt(stepId), parseInt(actionId), type, parseInt(index)]); 
    }
});