/*
 *  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.
 */
 
/**
 * Class for managing conditional results
 */
Ext.define('Ametys.plugins.workflow.actions.WorkflowResultAction', {
    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 {Number} _actionId id of current action parent
    */
   
    /**
    * @private
    * @property {Number} _resultId id of the targeted step in selected conditionl result
    */
   
    /**
    * @private
    * @property {Ametys.window.DialogBox} _addResultBox the creation dialog box for results
    */
    
    /**
    * @private
    * @property {Ametys.window.DialogBox} _editResultBox the edition dialog box for results
    */
    
    /**
     * Add a new conditional result
     * @param {Ametys.ribbon.element.ui.ButtonController} controller The controller calling this function
     */
    addConditionalResult: function(controller)
    {
        var target = Ametys.message.MessageTargetHelper.findTarget(controller.getMatchingTargets());
        var targetAction = target ? target.getSubtarget(function(target){return target.getId() == Ametys.message.MessageTarget.WORKFLOW_ACTION}) :  null;
        if (!targetAction)
        {
            return;
        }
        this._workflowName = targetAction.getParameters().workflowId;
        this._actionId = targetAction.getParameters().id;
        this._stepId = targetAction.getParameters().stepId;
        this._resultId = null;
        this._mode = "new";
        if (!this._addResultBox)
        {
            this._addResultBox = this._initDialogBox();
        }
        var finalStep = this._addResultBox.getComponent('conditionalFinalStep');
        finalStep.getStore().load({
            callback: Ext.bind(function(){
                var selectByDefault = finalStep.getStore().getData().items[0];
                if (selectByDefault)
                {
                    finalStep.setValue(selectByDefault.getId());
                }
                this._addResultBox.show();
            }, this)
        });
    },
    
    /**
     * @private
     * Create a dialog box for creating/editing a conditional result
     */
    _initDialogBox: function()
    {
        return Ext.create('Ametys.window.DialogBox',  {
            title : this._mode == "new" ? "{{i18n PLUGINS_WORKFLOW_ADD_RESULT_DIALOG_TITLE}}" : "{{i18n PLUGINS_WORKFLOW_EDIT_RESULT_DIALOG_TITLE}}",
            iconCls: this._mode == "new" ? "ametysicon-add64" : "ametysicon-edit45",
            
            width:400,
            layout: 'anchor',
            selectDefaultFocus: true,
            defaultFocus: 'conditionalFinalStep',
            defaults:
            {
                msgTarget: "side",
                cls: 'ametys',
                padding: 5,
                anchor: '100%',
                labelAlign: "top",
                labelSeparator: "",
                labelStyle: "font-weight:bold",
            },
            items : [
                {
                    xtype: "combobox",
                    itemId: 'conditionalFinalStep',
                    name: 'conditionalFinalStep',
                    fieldLabel: "{{i18n PLUGINS_WORKFLOW_CREATE_TRANSITION_FINAL_STATE_LABEL}}",
                    ametysDescription: "{{i18n PLUGINS_WORKFLOW_CREATE_TRANSITION_DIALOG_FINAL_STATE_DESC}}",
                    store: this._getStates(),
                    queryMode: 'local',
                    displayField: 'label',
                    valueField: 'id',
                    allowBlank: false,
                    editable: false
                }
            ],
            
            closeAction: 'hide',
            
            referenceHolder: true,
            defaultButton: 'validate',
            
            buttons : [
                {
                    reference: 'validate',
                    itemId:'validateCondition',
                    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)
                }
            ]
        });
    },
    
    /**
     * @private
     * Get the final states combobox's store data
     * @returns {Ext.data.Store} the final states store
     */
    _getStates: function()
    {
        var store = Ext.create('Ext.data.Store', {
            model: 'Ametys.plugins.workflow.models.WorkflowElementModel', 
            proxy: {
                type: 'ametys',
                role: 'org.ametys.plugins.workflow.dao.WorkflowResultDAO',
                methodName: 'getConditionalResultsToJson',
                methodArguments: ["workflowName", "actionId", "currentStepId"],
                reader: {
                    type: 'json',
                    rootProperty: 'data'
                }
             },
             autoLoad: true,
             listeners: {
                 'beforeload': {fn: this._onBeforeLoad, scope: this},
             }
        })
        return store;
    },
    
    /**
     * @private
     * Send the result values to server
     */
    _ok: function ()
    {
        var box = this._mode == "new" ? this._addResultBox : this._editResultBox;
        var stateValue = box.getComponent('conditionalFinalStep').getValue();
        
        this._mode == "new"
            ? Ametys.plugins.workflow.dao.WorkflowResultDAO.addConditionalResult([this._workflowName, parseInt(this._stepId), parseInt(this._actionId), stateValue], this._hideDialogBox, {scope: this})
            : Ametys.plugins.workflow.dao.WorkflowResultDAO.editConditionalResult([this._workflowName, parseInt(this._stepId), parseInt(this._actionId), parseInt(this._resultId), stateValue], this._hideDialogBox, {scope: this});
    },
    
    /**
     * Hide the dialog box
     */
    _hideDialogBox: function ()
    {
        var box = this._mode == "new" ? this._addResultBox : this._editResultBox;
        box.hide();
    },
    
    
    /**
     * @private
     * Set the workflow parameter to the request
     * @param {Ext.data.Store} store The store
     * @param {Ext.data.operation.Operation} operation The object that will be passed to the Proxy to load the store
     */
    _onBeforeLoad: function(store, operation)
    {
        operation.setParams(Ext.apply(operation.getParams() || {}, {
            workflowName: this._workflowName,
            actionId: parseInt(this._actionId),
            currentStepId: this._resultId != null ? parseInt(this._resultId) : null
        }));
    },
    
    /**
     * Edit a conditional result 
     * @param {Ametys.message.MessageTarget} target The result target
     */
    editConditionalResult: function(target)
    {
        this._workflowName = target.getParameters().workflowId;
        this._actionId = target.getParameters().actionId;
        this._stepId = target.getParameters().stepId;
        this._resultId = target.getParameters().nodeId.substring(4);
        
        this._mode = "edit";
        if (! this._editResultBox)
        {
            this._editResultBox = this._initDialogBox();
        }
        var comboFinalStep = this._editResultBox.getComponent('conditionalFinalStep');
        comboFinalStep.getStore().load(
        {
            callback: Ext.bind(function() {
                comboFinalStep.select(this._resultId);
            }, this)
        });
        this._editResultBox.getComponent('conditionalFinalStep').select(this._resultId);
        this._editResultBox.show();
    },
    
    /**
     * Delete a conditional result 
     * @param {Ametys.message.MessageTarget} resultTarget The result target
     */
    deleteConditionalResult: function(resultTarget)
    {
        var resultTargetParameters = resultTarget.getParameters();
        this._workflowName = resultTargetParameters.workflowId;
        this._actionId = resultTargetParameters.actionId;
        this._stepId = resultTargetParameters.stepId;
        var nodeId = resultTargetParameters.nodeId;
        var conditionalStepId = nodeId.substring(4);
        var conditionalStepLabel = resultTargetParameters.nodeLabel;
        
        Ametys.Msg.confirm("{{i18n PLUGINS_WORKFLOW_DELETE_RESULT_LABEL}}",
                Ext.String.format("{{i18n PLUGINS_WORKFLOW_DELETE_RESULT_CONFIRM}}", conditionalStepLabel),
                Ext.bind(this._doDelete, this, [conditionalStepId], 1),
                this
        );
    },
    
    /**
     * @private
     * Delete the step 
     * @param {String} btn The pressed button. Can only be 'yes'/'no'
     * @param {Number} conditionalStepId The target step to remove.
     */
    _doDelete: function(btn, conditionalStepId)
    {
        if (btn == 'yes')
        {
            Ametys.plugins.workflow.dao.WorkflowResultDAO.deleteConditionalResult([this._workflowName, parseInt(this._stepId), parseInt(this._actionId), parseInt(conditionalStepId)]);
        }   
    }
});