/*
 *  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 for MCC workflow
 * @private
 */
Ext.define('Ametys.plugins.odf.pilotage.actions.MCCWorkflowActions', {
	singleton: true,
	
	/**
	 * Do MCC workflow action
	 * @param {Ametys.ribbon.element.ui.ButtonController} controller The controller calling this function
	 */
	doMCCAction: function(controller, state)
	{
		if (!state)
		{
			// Already in current state, do nothing
			return;	
		}
		var contentIds = controller.getContentIds();
		
		var me = this;
		var minDateCheck = controller.getInitialConfig('min-date');
		if (minDateCheck)
		{
	        controller.serverCall (
	                minDateCheck, 
	                [contentIds], 
	                function (date) {
	                    Ametys.plugins.odf.pilotage.helper.ValidateDialog.open({
	                        dialogTitle: controller.getInitialConfig('label'),
	                        dialogIconCls: controller.getInitialConfig('icon-glyph') + " " + controller.getInitialConfig('on-icon-decorator'),
							hintMsg: controller.getInitialConfig('dialog-hint'),
							dateLabel: controller.getInitialConfig('date-label'),
	                        dateValue: new Date(),
	                        minDate: date ? new Date(date) : null,
	                        maxDate: new Date(),
	                        validateCallback: Ext.bind(me._doMCCAction, me, [controller, contentIds], 2)
	                    })
	                }
	        );
		}
		else
		{
			Ametys.plugins.odf.pilotage.helper.ValidateDialog.open({
                dialogTitle: controller.getInitialConfig('label'),
                dialogIconCls: controller.getInitialConfig('icon-glyph') + " " + controller.getInitialConfig('on-icon-decorator'),
                dateValue: new Date(),
                maxDate: new Date(),
                validateCallback: Ext.bind(me._doMCCAction, me, [controller, contentIds], 2)
            })
		}
	},

	/**
	 * @private
	 */	
	_doMCCAction: function (date, comment, controller, contentIds)
    {
        controller.serverCall (
                controller.getInitialConfig('server-method'), 
                [contentIds, date, comment, Ametys.getAppParameters()], 
                Ext.bind(this._doMCCActionCb, this, [controller, contentIds, controller.getInitialConfig('label')], 1), 
                { refreshing: true, errorMessage: true }
        );
    },
	
	undoMCCAction: function (controller)
	{
		var contentIds = controller.getContentIds();
		
		var me = this;
		Ametys.plugins.odf.pilotage.helper.InvalidateDialog.open({
            dialogTitle: controller.getInitialConfig('label'),
            dialogIconCls: controller.getInitialConfig('icon-glyph'),
			noReset: controller.getInitialConfig('no-reset') == "true",
            revertCallback: Ext.bind(me._undoMCCAction, me, [controller, contentIds], 3)
        })
	},
	
	/**
	 * @private
	 */	
	_undoMCCAction: function (sendMail, comment, reset, controller, contentIds)
    {
        controller.serverCall (
                controller.getInitialConfig('server-method'), 
                [contentIds, sendMail, comment, reset], 
                Ext.bind(this._doMCCActionCb, this, [controller, contentIds, controller.getInitialConfig('label')], 1), 
                { refreshing: true, errorMessage: true }
        );
    },
	
	/**
	 * @private
	 */	
	_doMCCActionCb: function (result, controller, contentIds, actionTitle)
    {
        if (result['error'] == "invalid-schedulable")
        {
            Ametys.Msg.show({
                title: "{{i18n PLUGINS_ODF_PILOTAGE_MCC_VALIDATED_PDF_CONTAINER_SCHEDULABLE_ACTION_ERROR}}",
                msg: "{{i18n PLUGINS_ODF_PILOTAGE_MCC_VALIDATED_PDF_CONTAINER_SCHEDULABLE_ACTION_ERROR_MSG}}",
                buttons: Ext.Msg.OK,
                icon: Ext.Msg.WARNING
            });
        }
        else
        {
            var successContentIds = result['success-contents'] || [];
            if (successContentIds.length > 0)
            {
                Ext.create("Ametys.message.Message", {
                    type: Ametys.message.Message.MODIFIED,
                    parameters: {major: true},
                    targets: {
                        id: Ametys.message.MessageTarget.CONTENT,
                        parameters: {
                            ids: successContentIds
                        }
                    }
                });
            }
			
			var warnMsg = this._buildWarnResultMsg(result);
            if (warnMsg)
            {
                Ametys.Msg.show({
                    title: actionTitle,
                    msg: warnMsg,
                    buttons: Ext.Msg.OK,
                    icon: Ext.Msg.WARNING
                });
            }
            
			var schedulable = result['schedulable-id'];
            if (result['schedulable-id'])
            {
                this._checkTaskState(schedulable, {
                    taskLabel: result['schedulable-label'],
                });
            }
        }
    },
	
	/**
	 * @private
	 */
	_buildWarnResultMsg: function(result)
	{
		var successContentIds = result['success-contents'] || [];
		            
        if (successContentIds.length > 0)
        {
            Ext.create("Ametys.message.Message", {
                type: Ametys.message.Message.MODIFIED,
                parameters: {major: true},
                targets: {
                    id: Ametys.message.MessageTarget.CONTENT,
                    parameters: {
                        ids: successContentIds
                    }
                }
            });
        }
        
        var noRightContents = result['noright-contents'] || [];
        var invalidContents = result['invalidmccstatus-contents'] || [];
        var lockedContents = result['locked-contents'] || [];
        
		var maxContents = 10;
		
        var warnMsg = "";
        if (noRightContents.length > 0)
        {
            warnMsg += "{{i18n plugin.odf-pilotage:PLUGINS_ODF_PILOTAGE_MCC_WORKFLOW_NO_RIGHT_ERROR}}";
            warnMsg += "<ul>";
            for(var i=0; i < Math.min(noRightContents.length, maxContents); i++)
            {
                warnMsg += "<li>" + noRightContents[i].title + "</li>";
            }
			if (noRightContents.length > maxContents)
			{
				warnMsg += "<li>" + Ext.String.format("{{i18n plugin.odf-pilotage:PLUGINS_ODF_PILOTAGE_MCC_WORKFLOW_OTHERS}}", noRightContents.length - maxContents) + "</li>";
			}
            warnMsg += "</ul>";
        }
		
        
        if (invalidContents.length > 0)
        {
            warnMsg += "{{i18n plugin.odf-pilotage:PLUGINS_ODF_PILOTAGE_MCC_WORKFLOW_INVALIDMCCSTATUS_ERROR}}";
            warnMsg += "<ul>";
            for(var i=0; i < Math.min(invalidContents.length, maxContents); i++)
            {
                warnMsg += "<li>" + invalidContents[i].title + "</li>";
            }
			if (invalidContents.length > maxContents)
			{
				warnMsg += "<li>" + Ext.String.format("{{i18n plugin.odf-pilotage:PLUGINS_ODF_PILOTAGE_MCC_WORKFLOW_OTHERS}}", invalidContents.length - maxContents) + "</li>";
			}
            warnMsg += "</ul>";
        }
        
        if (lockedContents.length > 0)
        {
            warnMsg += "{{i18n plugin.odf-pilotage:PLUGINS_ODF_PILOTAGE_MCC_WORKFLOW_LOCKED_ERROR}}";
            warnMsg += "<ul>";
            for(var i=0; i < Math.min(lockedContents.length, maxContents); i++)
            {
                warnMsg += "<li>" + lockedContents[i].title + "</li>";
            }
			if (lockedContents.length > maxContents)
			{
				warnMsg += "<li>" + Ext.String.format("{{i18n plugin.odf-pilotage:PLUGINS_ODF_PILOTAGE_MCC_WORKFLOW_OTHERS}}", lockedContents.length - maxContents) + "</li>";
			}
            warnMsg += "</ul>";
        }
        
        var schedulable = result['schedulable-id'];
        if (warnMsg)
        {
            if (successContentIds.length > 0 && schedulable)
            {
                warnMsg += "<br/>" + Ext.String.format("{{i18n plugin.odf-pilotage:PLUGINS_ODF_PILOTAGE_MCC_VALIDATED_PDF_CONTAINER_CFVU_ERROR_MSG}}", successContentIds.length)
            }
        }
		
		return warnMsg;
	},
    
    /**
     * Validates the MCC for orgunit level for all years of the selected program
     * @param {Ametys.ribbon.element.ui.ButtonController} controller The controller calling this function
     * @param {Boolean} state the state of the button
     */
    validateOrgunitMCCForChildYears: function (controller, state)
    {
        var programIds = controller.getContentIds();
        
        if (programIds.length > 0)
        {
            var me = this;
            controller.serverCall (
                    'getMinDateForMCCOrgUnitValidation', 
                    [programIds[0]], 
                    function (date) {
                        Ametys.plugins.odf.pilotage.helper.ValidateDialog.open({
                            dialogTitle: "{{i18n PLUGINS_ODF_PILOTAGE_MCC_WORKFLOW_PROGRAM_MCC_ORGUNIT_VALIDATION_LABEL}}",
                            dialogIconCls: "ametysicon-desktop-clipboard-list decorator-ametysicon-sign-raw-check",
                            dateValue: new Date(),
							dateLabel: "{{i18n PLUGINS_ODF_PILOTAGE_CONTAINER_MCC_WORKFLOW_ORGUNIT_VALIDATION_DATE_LABEL}}",
                            minDate: date ? new Date(date) : null,
                            maxDate: new Date(),
                            validateCallback: Ext.bind(me._validateOrgunitMCCForChildYears, me, [controller, programIds[0]], 2)
                        })
                    }
            );
        }
    },
    
	/**
	 * @private
	 */
    _validateOrgunitMCCForChildYears: function (date, comment, controller, programId)
    {
        controller.serverCall (
                'validateOrgunitMCC', 
                [programId, date, comment], 
                Ext.bind(this._updateProgramMCCStatusCb, this, [controller, [programId], "{{i18n PLUGINS_ODF_PILOTAGE_MCC_WORKFLOW_PROGRAM_MCC_ORGUNIT_VALIDATION_LABEL}}", "{{i18n PLUGINS_ODF_PILOTAGE_MCC_WORKFLOW_PROGRAM_MCC_ORGUNIT_VALIDATION_SUCCESS}}"], 1), 
                { refreshing: true, errorMessage: true }
        );
    },
    
    /**
     * Validates the MCC for CFVU level for all years of the selected program
     * @param {Ametys.ribbon.element.ui.ButtonController} controller The controller calling this function
     * @param {Boolean} state the state of the button
     */
    validateCFVUMCCForChildYears: function (controller, state)
    {
        var programIds = controller.getContentIds();
        
        if (programIds.length > 0)
        {
            var me = this;
            controller.serverCall (
                    'getMinDateForMCCCFVUValidation', 
                    [programIds[0]], 
                    function (date) {
                        Ametys.plugins.odf.pilotage.helper.ValidateDialog.open({
                            dialogTitle: "{{i18n PLUGINS_ODF_PILOTAGE_MCC_WORKFLOW_PROGRAM_MCC_CFVU_VALIDATION_LABEL}}",
                            dialogIconCls: "ametysicon-desktop-clipboard-list decorator-ametysicon-sign-raw-check",
                            dateValue: new Date(),
							dateLabel: "{{i18n PLUGINS_ODF_PILOTAGE_CONTAINER_MCC_WORKFLOW_CFVU_VALIDATION_DATE_LABEL}}",
                            hintMsg: "{{i18n plugin.odf-pilotage:PLUGINS_ODF_PILOTAGE_MCC_VALIDATED_PDF_CONTAINER_CFVU_HINT}}",
                            minDate: date ? new Date(date) : null,
                            maxDate: new Date(),
                            validateCallback: Ext.bind(me._validateCFVUMCCForChildYears, me, [controller, programIds[0]], 2)
                        })
                    }
            );
        }
    },
    
    /**
	 * @private
	 */
    _validateCFVUMCCForChildYears: function (date, comment, controller, programId)
    {
        controller.serverCall (
                'validateMCCForCVFU', 
                [programId, date, comment, Ametys.getAppParameters()], 
                Ext.bind(this._updateProgramMCCStatusCb, this, [controller, [programId], "{{i18n PLUGINS_ODF_PILOTAGE_MCC_WORKFLOW_PROGRAM_MCC_CFVU_VALIDATION_LABEL}}", "{{i18n PLUGINS_ODF_PILOTAGE_MCC_WORKFLOW_PROGRAM_MCC_CFVU_VALIDATION_SUCCESS}}"], 1), 
                { refreshing: true, errorMessage: true }
        );
    },
    
	/**
	 * @private
	 */
    _updateProgramMCCStatusCb: function (result, controller, programIds, actionTitle, successMsg)
    {
        var successContentIds = result['success-contents'] || [];
        
        if (successContentIds.length > 0)
        {
            Ametys.cms.content.ContentDAO.getContents(programIds, function(contents) {
                Ext.Array.forEach(contents, function(content) {
                    var infoMsg = Ext.String.format(successMsg, successContentIds.length, content.getTitle());
					if (result['schedulable-id'])
		            {
		                infoMsg += "<br/><br/>{{i18n plugin.odf-pilotage:PLUGINS_ODF_PILOTAGE_MCC_VALIDATED_PDF_CONTAINER_CFVU_SUCCESS_MSG}}";
		            }
                     Ametys.notify({
		                type: 'info',
		                iconGlyph: 'ametysicon-sign-raw-check',
		                title: actionTitle,
		                description: infoMsg
		            });
                })
            })
        }
        
        this._doMCCActionCb(result, controller, programIds, actionTitle);
    },
    
	
	/**
     * Validates the MCC for orgunit level for all years of the selected orgunit
     * @param {Ametys.ribbon.element.ui.ButtonController} controller The controller calling this function
     * @param {Boolean} state the state of the button
     */
    validateOrgunitMCCForOrgunitYears: function (controller, state)
    {
		var me = this;
        var ouIds = controller.getContentIds();
        if (ouIds.length > 0)
        {
			Ametys.plugins.odf.pilotage.helper.ValidateDialog.open({
                dialogTitle: "{{i18n PLUGINS_ODF_PILOTAGE_MCC_WORKFLOW_ORGUNIT_MCC_ORGUNIT_VALIDATION_LABEL}}",
                dialogIconCls: "ametysicon-desktop-clipboard-list decorator-ametysicon-sign-raw-check",
                dateValue: new Date(),
				dateLabel: "{{i18n PLUGINS_ODF_PILOTAGE_CONTAINER_MCC_WORKFLOW_ORGUNIT_VALIDATION_DATE_LABEL}}",
				withCatalog: true,
                validateCallback: Ext.bind(me._validateOrgunitMCCForOrgunitYears, me, [controller, ouIds[0]], 3)
            })
        }
    },
    
	/**
	 * @private
	 */
    _validateOrgunitMCCForOrgunitYears: function (catalog, date, comment, controller, ouId)
    {
		var me = this;
		Ametys.Msg.confirm("{{i18n PLUGINS_ODF_PILOTAGE_MCC_WORKFLOW_ORGUNIT_MCC_ORGUNIT_VALIDATION_LABEL}}",
            "{{i18n PLUGINS_ODF_PILOTAGE_MCC_WORKFLOW_ORGUNIT_MCC_ORGUNIT_VALIDATION_CONFIRM}}",
            function(answer)
            {
                if (answer == 'yes')
                {
					Ametys.cms.content.ContentDAO.getContent(ouId, function(ouContent) {
						var actionTitle = Ext.String.format("{{i18n PLUGINS_ODF_PILOTAGE_MCC_WORKFLOW_ORGUNIT_MCC_ORGUNIT_VALIDATION_TITLE}}", ouContent.getTitle());
						controller.serverCall (
			                'validateOrgunitMCC', 
			                [ouId, catalog, date, comment], 
			                Ext.bind(me._updateOrgunitMCCStatusCb, me, [controller, ouContent, actionTitle, "{{i18n PLUGINS_ODF_PILOTAGE_MCC_WORKFLOW_ORGUNIT_MCC_ORGUNIT_VALIDATION_SUCCESS}}"], 1), 
			                { refreshing: true, errorMessage: true, priority: Ametys.data.ServerComm.PRIORITY_LONG_REQUEST }
				        );
					});
				}
			}
		);
    },
	
	/**
     * Validates the MCC for CFVU level for all years of the selected orgunit
     * @param {Ametys.ribbon.element.ui.ButtonController} controller The controller calling this function
     * @param {Boolean} state the state of the button
     */
    validateCFVUMCCForOrgunitYears: function (controller)
    {
		var me = this;
        var ouIds = controller.getContentIds();
        if (ouIds.length > 0)
        {
			Ametys.plugins.odf.pilotage.helper.ValidateDialog.open({
                dialogTitle: "{{i18n PLUGINS_ODF_PILOTAGE_MCC_WORKFLOW_ORGUNIT_MCC_CFVU_VALIDATION_LABEL}}",
                dialogIconCls: "ametysicon-desktop-clipboard-list decorator-ametysicon-sign-raw-check",
                hintMsg: "{{i18n plugin.odf-pilotage:PLUGINS_ODF_PILOTAGE_MCC_VALIDATED_PDF_CONTAINER_CFVU_HINT}}",
				dateLabel: "{{i18n PLUGINS_ODF_PILOTAGE_CONTAINER_MCC_WORKFLOW_CFVU_VALIDATION_DATE_LABEL}}",
                dateValue: new Date(),
				withCatalog: true,
                validateCallback: Ext.bind(me._validateCFVUMCCForOrgunitYears, me, [controller, ouIds[0]], 3)
            })
        }
    },
    
    /**
	 * @private
	 */
    _validateCFVUMCCForOrgunitYears: function (catalog, date, comment, controller, ouId)
    {
		var me = this;
		Ametys.Msg.confirm("{{i18n PLUGINS_ODF_PILOTAGE_MCC_WORKFLOW_ORGUNIT_MCC_CFVU_VALIDATION_LABEL}}",
            "{{i18n PLUGINS_ODF_PILOTAGE_MCC_WORKFLOW_ORGUNIT_MCC_CFVU_VALIDATION_CONFIRM}}",
            function(answer)
            {
                if (answer == 'yes')
                {
					Ametys.cms.content.ContentDAO.getContent(ouId, function(ouContent) {
						
						var actionTitle = Ext.String.format("{{i18n PLUGINS_ODF_PILOTAGE_MCC_WORKFLOW_ORGUNIT_MCC_CFVU_VALIDATION_TITLE}}", ouContent.getTitle());
						controller.serverCall (
			                'validateMCCForCVFU', 
			                [ouId, catalog, date, comment, Ametys.getAppParameters()], 
			                Ext.bind(me._updateOrgunitMCCStatusCb, me, [controller, ouContent, actionTitle, "{{i18n PLUGINS_ODF_PILOTAGE_MCC_WORKFLOW_ORGUNIT_MCC_CFVU_VALIDATION_SUCCESS}}"], 1), 
			                { refreshing: true, errorMessage: true, priority: Ametys.data.ServerComm.PRIORITY_LONG_REQUEST }
				        );
					});
				}
			}
		);
    },
	
	/**
	 * @private
	 */
    _updateOrgunitMCCStatusCb: function (result, controller, ouContent, actionTitle, successMsg)
    {
        var successContentIds = result['success-contents'] || [];
        
        if (successContentIds.length > 0)
        {
			var infoMsg = Ext.String.format(successMsg, successContentIds.length, ouContent.getTitle());
			if (result['schedulable-id'])
            {
                infoMsg += "<br/><br/>{{i18n plugin.odf-pilotage:PLUGINS_ODF_PILOTAGE_MCC_VALIDATED_PDF_CONTAINER_CFVU_SUCCESS_MSG}}";
            }
             Ametys.notify({
                type: 'info',
                iconGlyph: 'ametysicon-sign-raw-check',
                title: actionTitle,
                description: infoMsg
            });
        }
        
        var warnMsg = this._buildWarnResultMsg(result);
		if (warnMsg)
		{
			Ametys.notify({
                type: 'warn',
                iconGlyph: 'ametysicon-sign-raw-check',
                title: actionTitle,
                description: warnMsg
            });
		}
		
		var schedulable = result['schedulable-id'];
        if (result['schedulable-id'])
        {
            this._checkTaskState(schedulable, {
                taskLabel: result['schedulable-label'],
            });
        }
    },
		
    /**
     * Check the task state
     * @param {String} taskId the task id
     * @param {Object} args the given arguments
     * @private
     */
    _checkTaskState: function(taskId, args)
    {
        Ametys.plugins.core.schedule.Scheduler.getTasksInformation(
            [[taskId]], 
            this._checkTaskStateCb, 
            {
                errorMessage: Ext.String.format("{{i18n plugin.core-ui:PLUGINS_CORE_UI_TASKS_ADD_TASK_BUTTON_CONTROLLER_CHECK_STATE_ERROR}}", args.taskLabel),
                scope: this, 
                arguments: args
            }
        );
    },
    
    /**
     * Callback after checking the task state
     * @param {Object} response the response
     * @param {Object} args the given arguments
     * @private
     */
    _checkTaskStateCb: function(response, args)
    {
        if (response.length > 0)
        {
            var task = response[0];
            if (task.getState() == "running")
            {
                Ext.defer(this._checkTaskState, 5000, this, [task.getId(), args]);
            }
            else if (task.getState() == "success")
            {
               Ametys.notify({
                    type: 'info',
                    title: args.taskLabel,
                    description: "{{i18n PLUGINS_ODF_PILOTAGE_MCC_VALIDATED_PDF_CONTAINER_SCHEDULABLE_ENDED_SUCCESS}}"
                });
            }
            else if (task.getState() == "failure")
            {
               Ametys.notify({
                    type: 'error',
                    title: args.taskLabel,
                    description: "{{i18n PLUGINS_ODF_PILOTAGE_MCC_VALIDATED_PDF_CONTAINER_SCHEDULABLE_ENDED_FAILURE}}"
                });
            }
        }
    },
    
    /**
     * Action function to be called by the controller.
     * Will open the dialog box to edit validated MCC, only permitted action is deleting MCC's pdf because addition is blocked by unavailable mandatory fields
     * @param {Ametys.ribbon.element.ui.ButtonController} controller The controller calling this function
     */
    seeValidatedMCC: function(controller)
    {
        var contentIds = controller.getContentIds()
        if (contentIds.length > 0)
        {
            var targets = controller.getMatchingTargets().filter(t => t.getParameters().id == contentIds[0])
            if (targets.length > 0)
            {
                var target = targets[0];
                var rights = target.getParameters().rights || [];
                var disallowEdition = !Ext.Array.contains(rights, "ODF_Pilotage_Delete_MCC_Validated_Rights");
                
                var openParams = {
                    content: target.getParameters().content,
                    editWorkflowActionId: 222227,
                    iconCls: 'ametysicon-interface decorator-ametysicon-body-part-eye',
                    viewName: "mcc-validated-pdf",
                    width: 800,
                    labelAlign: 'right',
                    title: "{{i18n PLUGINS_ODF_PILOTAGE_MCC_VALIDATED_PDF_SEE_DIALOG_TITLE}} "  + "\"" + target.getParameters().title + "\"",
                    disallowEdition: disallowEdition
                }
            
                Ametys.cms.uihelper.EditContent.open(openParams, null, this);
            }
        }
    }
    
});