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

/**
 * Singleton class defining the actions related to the alerts on contents.
 * @private
 */
Ext.define('Ametys.plugins.cms.content.actions.AlertsActions', {
	singleton: true,
	
	/**
	 * @private
	 * @property {Ext.Template} _unmodifiedLabelTpl Template for unmodified alert
	 */
	_unmodifiedLabelTpl: new Ext.Template ("{{i18n CONTENT_ALERTS_DIALOG_FIELD_UNMODIFIED_ALERT_LABEL_1}}", '{delay}', "{{i18n CONTENT_ALERTS_DIALOG_FIELD_UNMODIFIED_ALERT_LABEL_2}}"),
	
	/**
	 * @private 
	 * @property {String[]} _contentIds The contents' ids
	 */
	_contentIds: [],
	
	/**
	 * Set alerts on selected contents
	 * @param {Ametys.ribbon.element.ui.ButtonController} controller The controller calling this function
	 */
	act: function (controller)
	{
        var contentIds = controller.getContentIds();
        if (contentIds.length > 0)
        {
            controller.serverCall('getAlertsInformations', [contentIds], Ext.bind(this._getAlertsInformationsCb, this), 
                { 
                    errorMessage: { msg: "{{i18n CONTENT_ALERTS_DIALOG_RETRIEVE_STATE_ERROR}}", category: 'Ametys.plugins.cms.content.actions.AlertsActions'},
                    refreshing: true,
                    arguments: {controller: controller}
                }
            )
        };
	},
	
	/**
	 * @private
     * Callback function called after #_initForm to initialize the form
     * @param {Object} response The server response
     * @param {Object[]} response.alert-disabled-contents  the array containing the contents which do not have a reminder 
     * @param {String} response.alert-disabled-contents.id  the content's id
     * @param {String} response.alert-disabled-contents.title  the content's title
     * @param {String} response.alert-disabled-contents.description  the content's description
     * @param {Object[]} response.alert-enabled-contents  the array containing the contents which have a reminder 
     * @param {String} response.alert-enabled-contents.id  the content's id
     * @param {String} response.alert-enabled-contents.title  the content's title
     * @param {String} response.alert-enabled-contents.description  the content's description
     * @param {Object[]} response.all-right-contents  the array containing the contents with all the rights 
     * @param {String} response.all-right-contents.id  the content's id
     * @param {String} response.all-right-contents.title  the content's title
     * @param {String} response.all-right-contents.description  the content's description
     * @param {Number} response.validation-alert-delay the numbers of days before a non-validated content will be having an alert 
     * @param {Number} response.unmodified-alert-delay the numbers of days before an unmodified content will be having an alert ( if checked )
     * @param {boolean} response.reminderEnabled the boolean true when the reminder is enabled
     * @param {boolean} response.unmodifiedAlertEnabled the boolean true when the reminder for unmodified content is enabled
     * @param {String} response.reminderText the text of the reminder
     * @param {String} response.reminderDate the date of the reminder
     */
	_getAlertsInformationsCb: function (response, args)
	{
        this._contentIds = response.contentIds;
        
        this._createDialogBox(response['unmodified-alert-delay'], args.controller);
        
        this._initForm(response);
        
        this._box.show();
    },
	
	/**
	 * @private
	 */
	_initForm: function (response)
	{
		var form = this._form.getForm();
		
		// Unmodified alert
		var unmodifiedAlertEnabled = response['unmodifiedAlertEnabled'];
		var unmodifiedAlertText = response['unmodifiedAlertText'];
		
		if (response['unmodified-alert-delay'] > 0)
		{
			form.findField('unmodifiedAlertText').setValue(unmodifiedAlertText);
			form.findField('unmodifiedAlertText').setDisabled(unmodifiedAlertEnabled !== true);
			form.findField('unmodifiedAlertEnabled').setValue(this._convertBoolean2TricheckboxValue(unmodifiedAlertEnabled));
		}
		else
		{
			form.findField('unmodifiedAlertEnabled').setValue('0');
			form.findField('unmodifiedAlertText').setValue(null);
			form.findField('unmodifiedAlertText').disable();
		}
		
		// Reminder alert
		var reminderEnabled = response['reminderEnabled'];
		var reminderDate = response['reminderDate'];
		var reminderText = response['reminderText'];
		
		form.findField('reminderEnabled').setValue(this._convertBoolean2TricheckboxValue(reminderEnabled));
        
		// Enable/Disable fields
		form.findField('reminderText').setDisabled(reminderEnabled !== true);
        form.findField('reminderDate').setDisabled(reminderEnabled !== true);
        
        form.findField('reminderDate').setValue(reminderDate);
        form.findField('reminderText').setValue(reminderText);
    },
    
    /**
     * @private
     * Converts the given value from server to string value for tri-state checkbox
     * @param {Boolean} value as boolean. Can be null.
     * @return {String} the converted value
     */
    _convertBoolean2TricheckboxValue: function (value)
    {
    	if (value === null)
    	{
    		return 'null';
    	}
    	return value === true ? '1' : '0';
    },
    
    /**
     * @private
     * Converts the tri-state checkbox value to boolean value
     * @param {String} value tri-state checkbox value
     * @return {Boolean} the converted value. Can be null.
     */
    _convertTricheckboxValue2Boolean: function (value)
    {
    	if (value == 'null')
    	{
    		return null;
    	}
    	return value == '1' ? true : false;
    },
	
	/**
	 * @private
	 * Creates the dialog box
	 * @param {Number} unmodifiedAlertDelay Delay for unmodified content alert
	 * @param {Ametys.ribbon.element.ui.ButtonController} controller, in order to use the serverCall method
	 */
	_createDialogBox: function (unmodifiedAlertDelay, controller)
	{
		this._form = this._createFormPanel(unmodifiedAlertDelay);
		
		this._box = Ext.create('Ametys.window.DialogBox', {
			title :"{{i18n CONTENT_ALERTS_DIALOG_TITLE}}",
			iconCls : 'ametysicon-bell84',
			
			width: 450,
			maxHeight: 650,
			scrollable: true,
			
			layout: {
				type: 'vbox',
				align: 'stretch'
			},
			
			items : [ this._form ],
			
			defaultFocus: 'instant-alert-enabled',
			closeAction: 'destroy',
			
			referenceHolder: true,
			defaultButton: 'save',
			
			buttons : [{
				reference: 'save',
				text :"{{i18n CONTENT_ALERTS_DIALOG_BUTTON_OK}}",
				handler : function() {this._saveAlerts(controller)},
				scope: this
			}, {
				text :"{{i18n CONTENT_ALERTS_DIALOG_BUTTON_CANCEL}}",
				handler : function () { this._box.close()},
				scope: this
			} ]
		});
	},
	
	/**
	 * @private
	 * Save the alerts
	 * @param {Ametys.ribbon.element.ui.ButtonController} controller, in order to use the serverCall method
	 */
	_saveAlerts: function (controller)
	{		
		var form = this._form.getForm();
		
		if (!form.isValid())
		{
			return;
		}
		
		var date = form.findField('reminderDate').getValue();
		if (form.findField('reminderEnabled').getValue() == '1' && (!date || date == ''))
		{
			form.findField('reminderDate').markInvalid("{{i18n CONTENT_ALERTS_DIALOG_ERROR_NO_REMINDER_DATE}}");
			return;
		}
		
		var params = form.getValues();
		params.reminderEnabled = this._convertTricheckboxValue2Boolean (params.reminderEnabled);
		params.unmodifiedAlertEnabled = this._convertTricheckboxValue2Boolean (params.unmodifiedAlertEnabled);
        params['schedulable-id'] = controller['schedulable-id'];
        
		controller.serverCall('setAlertsOnContent', [this._contentIds, params], Ext.bind(this._saveAlertsCb,this), 
							{ 
								errorMessage : { msg: "{{i18n CONTENT_ALERTS_DIALOG_ERROR_SETTING_ALERTS}}", category: 'Ametys.plugins.cms.content.actions.AlertsActions'},
                                refreshing: true
							}
        );
	},
	
	/**
	 * @private
	 * Callback function called after the saving of alerts succeeded
	 * @param {Object} response The server response.
	 */
	_saveAlertsCb: function (response)
	{
        var successContents = response['success-content-ids'];
        if (successContents.lenght > 0)
        {
    		Ext.create("Ametys.message.Message", {
    			type: Ametys.message.Message.MODIFIED,
    			parameters: {major: false},
    			targets: {
    				id: Ametys.message.MessageTarget.CONTENT,
    				parameters: { ids: this._contentIds }
    			}
    		});
        }
        
        var noRightContents = response['no-right-contents'];
        var errorContents = response['error-contents'];
        if (noRightContents.lenght > 0 || errorContents.length > 0)
        {
            var message = "";
            if (errorContents.length > 0)
            {
                message += "{{i18n CONTENT_ALERTS_DIALOG_ERROR_SETTING_ALERTS}}"
                message += "<ul>"
                for (var i=0; i < errorContents.length; i++)
                {
                    if (i != 0) 
                    {
                        message += ", ";
                    }
                    message += `<li>${errorContents[i].title}</li>`;
                }
                message += "</ul>";
            }
            
            if (noRightContents.length > 0)
            {
                message += "{{i18n CONTENT_ALERTS_DIALOG_NO_RIGHT_SETTING_ALERTS}}"
                message += "<ul>"
                for (var i=0; i < noRightContents.length; i++)
                {
                    if (i != 0) 
                    {
                        message += ", ";
                    }
                    message += `<li>${noRightContents[i].title}</li>`;
                }
                message += "</ul>";
            }
        }
        
		this._box.hide();
	},
	
	/**
	 * @private
	 * Creates the form panel
	 * @param {Number} unmodifiedAlertDelay Delay for unmodified content alert
	 */
	_createFormPanel: function (unmodifiedAlertDelay)
	{
		var items = [
		    // Hint text
		    {
				type: 'component',
				cls: 'a-text',
				html: "{{i18n CONTENT_ALERTS_DIALOG_HINT_TEXT}}"
			}, 
			// Instant alert
			{
				xtype: 'checkboxfield',
	            name: 'instantAlertEnabled',
	            itemId: 'instant-alert-enabled',
	            boxLabel: "{{i18n CONTENT_ALERTS_DIALOG_FIELD_INSTANT_ALERT_LABEL}}",
	            ametysDescription: "{{i18n CONTENT_ALERTS_DIALOG_FIELD_INSTANT_ALERT_DESC}}",
	            hideLabel: true,
	            inputValue: true,
				uncheckedValue: false,
	            style: {marginLeft: '10px'},
	            width: 415,
	            listeners: {
					'change': Ext.bind (this._onCheckInstantAlert, this)
				}
			},
			{
				xtype: 'textarea',
	            name: 'instantAlertText',
				fieldLabel: "{{i18n CONTENT_ALERTS_DIALOG_FIELD_INSTANT_ALERT_TEXT_LABEL}}",
				ametysDescription: "{{i18n CONTENT_ALERTS_DIALOG_FIELD_INSTANT_ALERT_TEXT_DESC}}",
	            height: 90,
	            allowBlank: false,
	            disabled: true,
	            style: {marginLeft: '25px'},
	            width: 400
			}
		];
		
		if (unmodifiedAlertDelay > 0)
		{
			items.push({
				xtype: 'tricheckbox',
				name: 'unmodifiedAlertEnabled',
				enableNullValueOnBoxClick: false,
				inputValue: true,
				uncheckedValue: false,
				boxLabel: this._unmodifiedLabelTpl.apply({'delay': unmodifiedAlertDelay}),
				ametysDescription: "{{i18n CONTENT_ALERTS_DIALOG_FIELD_UNMODIFIED_ALERT_DESC}}",
				style: {marginLeft: '10px'},
				width: 415,
				listeners: {
					'tristatechange': Ext.bind (this._onCheckUnmodifiedAlert, this)
				}
			});
			items.push({
				xtype: 'textarea',
	            name: 'unmodifiedAlertText',
				fieldLabel: "{{i18n CONTENT_ALERTS_DIALOG_FIELD_UNMODIFIED_ALERT_TEXT_LABEL}}",
				ametysDescription: "{{i18n CONTENT_ALERTS_DIALOG_FIELD_UNMODIFIED_ALERT_TEXT_DESC}}",
				disabled: true,
	            style: {marginLeft: '25px'},
	            height: 90,
	            width: 400
			});
		}
		else
		{
			items.push({
				xtype: 'hiddenfield',
				name: 'unmodifiedAlertEnabled',
				value: 'false'
			});
		}
		
		items.push ({
			layout: {
                type: 'hbox'
            },
			border: false,
			defaults: {
				cls: 'ametys'
			},
			items: [{
					xtype: 'tricheckbox',
					enableNullValueOnBoxClick: false,
					name: 'reminderEnabled',
					inputValue: true,
					uncheckedValue: false,
					boxLabel: "{{i18n CONTENT_ALERTS_DIALOG_FIELD_REMINDER_LABEL}}",
					style: {marginLeft: '10px'},
					width: 150,
					listeners: {
						'tristatechange': Ext.bind (this._onCheckReminder, this)
					}
				},{
					xtype: 'edition.date',
					name: 'reminderDate',
					hideLabel: true,
					disabled: true,
					width: 415 - 150
			}]
		});
		
		items.push({
			xtype: 'textarea',
			name: 'reminderText',
			fieldLabel: "{{i18n CONTENT_ALERTS_DIALOG_FIELD_REMINDER_TEXT_LABEL}}",
			ametysDescription: "{{i18n CONTENT_ALERTS_DIALOG_FIELD_REMINDER_TEXT_DESC}}",
			disabled: true,
			allowBlank: false,
			style: {marginLeft: '25px'},
			width: 400,
            height: 90
		});
		
		return Ext.create('Ext.form.Panel', {
			border: false,
			defaults: {
				cls: 'ametys',
				labelAlign: 'top'
			},
			items: items
		});
	},
	
	/**
	 * @private
	 * Listener when reminder checkbox is checked
	 * @param {Ext.form.field.Field} checkbox The checkbox
	 * @param {Boolean} value The value
	 */
	_onCheckReminder: function (checkbox, value)
	{
		this._form.getForm().findField('reminderDate').setDisabled(value != '1');
		this._form.getForm().findField('reminderText').setDisabled(value != '1');
	},
	
	/**
	 * @private
	 * Listener when instant alert checkbox is checked
	 * @param {Ext.form.field.Field} checkbox The checkbox
	 * @param {Boolean} value The value
	 */
	_onCheckInstantAlert: function (checkbox, value)
	{
		this._form.getForm().findField('instantAlertText').setDisabled(!value);
	},
	
	/**
	 * @private
	 * Listener when instant alert checkbox is checked
	 * @param {Ext.form.field.Field} checkbox The checkbox
	 * @param {Boolean} value The value
	 */
	_onCheckUnmodifiedAlert: function (checkbox, value)
	{
		this._form.getForm().findField('unmodifiedAlertText').setDisabled(value != '1');
	}
	
});