/*
 *  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.
 */
/**
 * This class is a singleton to handle actions to force subscriptions.
 */
Ext.define('Ametys.plugins.page.subscription.ForceSubscriptionsActions', {
    singleton: true, 
    
    /**
     * Subscribe to force a group subscription
     * @param {Ametys.ribbon.element.ui.ButtonController} controller The controller calling this function.
     */
    forceGroupSubscription: function(controller)
    {
        Ametys.data.ServerComm.callMethod({
            role: "org.ametys.plugins.pagesubscription.dao.ForceTagSubscriptionsDAO",
            methodName: "getFrequencyTiming",
            parameters: [],
            callback: {
                handler: this._getFrequencyTiming,
                scope: this
            },
            errorMessage: true,
            waitMessage: true
        });
    },
    
    /**
     * Callback after getting the frequency timing
     * @param {Object} response The response
     * @private
     */
    _getFrequencyTiming: function(response)
    {
        this._createSubscriptionDialog();

        this._box.down("#group").enable();
        this._box.down("#tag").enable();
        this._formPanel.reset();
        this._box.down("#day").setValue(response.day);
        this._box.down("#hour").setValue(response.hour);
        this._box.down("#frequency").setValue("WEEKLY");
        this._box.show();
    },
    
    /**
     * Create the subscription dialog
     * @private
     */
    _createSubscriptionDialog: function()
    {
        if (!this._box)
        {
            this._formPanel = this._createFormPanel();
            
            this._box = Ext.create('Ametys.window.DialogBox', {
                title : "{{i18n PLUGINS_PAGE_SUBSCRIBE_USER_SUBSCRIPTIONS_FORCE_CREATE_DIALOG_BOX_TITLE}}",
                iconCls : "ametysicon-desktop-opened29",
                maxHeight: window.innerHeight * 0.80,
                
                items: [this._formPanel],
                
                selectDefaultFocus: true,
                closeAction: 'hide',
                
                referenceHolder: true,
                defaultButton: 'validate',
                
                buttons : [
                    {
                        reference: 'validate',
                        text: "{{i18n PLUGINS_PAGE_SUBSCRIBE_USER_SUBSCRIPTIONS_FORCE_CREATE_DIALOG_BOX_VALIDATE}}",
                        handler: Ext.bind(this._validateForm, this),
                        scope: this
                    }, {
                        text: "{{i18n PLUGINS_PAGE_SUBSCRIBE_USER_SUBSCRIPTIONS_FORCE_CREATE_DIALOG_BOX_CANCEL}}",
                        handler: Ext.bind( function() {this._box.close();}, this),
                        scope: this
                }]
            });
        }
    },
    
    /**
     * Create the form panel
     * @private
     */
    _createFormPanel: function()
    {
        return Ext.create('Ext.form.Panel', {
            layout: {
                type: 'vbox',
                align: 'stretch'
            },
            width: 400,
            defaults: {
                cls: 'ametys',
                labelAlign: 'top',
                labelSeparator: '',
                style: 'margin-left: 5px',
                msgTarget: 'side'
            },
            items: [
                {
                    xtype: 'edition.hidden',
                    name: 'id',
                    id: 'id'
                },
                {
                    xtype: 'edition.group',
                    name: 'allowedGroups',
                    fieldLabel: "{{i18n PLUGINS_PAGE_SUBSCRIBE_USER_SUBSCRIPTIONS_FORCE_GROUP_FIELD_LABEL}}",
                    ametysDescription: "{{i18n PLUGINS_PAGE_SUBSCRIBE_USER_SUBSCRIPTIONS_FORCE_GROUP_FIELD_DESC}}",
                    name: "group",
                    id: "group",
                    allowBlank: false,
                },
                {
                    xtype: 'edition.tag',
                    fieldLabel: '{{i18n PLUGINS_PAGE_SUBSCRIBE_USER_SUBSCRIPTIONS_FORCE_TAG_FIELD_LABEL}}',
                    ametysDescription: "{{i18n PLUGINS_PAGE_SUBSCRIBE_USER_SUBSCRIPTIONS_FORCE_TAG_FIELD_DESC}}",
                    name: "tag",
                    id: "tag",
                    allowBlank: false,
                    targetType: 'CONTENT'
                },
                this._getFrequencyCombobox(),
                this._getDayCombobox(),
                {
                    xtype: 'edition.string-time',
                    fieldLabel: "{{i18n PLUGINS_PAGE_SUBSCRIBE_USER_SUBSCRIPTIONS_FORCE_HOUR_FIELD_LABEL}}",
                    ametysDescription: "{{i18n PLUGINS_PAGE_SUBSCRIBE_USER_SUBSCRIPTIONS_FORCE_HOUR_FIELD_DESC}}",
                    name: 'hour',
                    id: 'hour'
                },
                {
                    xtype: 'checkboxgroup',
                    fieldLabel: "{{i18n PLUGINS_PAGE_SUBSCRIBE_USER_SUBSCRIPTIONS_FORCE_BROADCAST_CHANNEL_FIELD_LABEL}}",
                    ametysDescription: "{{i18n PLUGINS_PAGE_SUBSCRIBE_USER_SUBSCRIPTIONS_FORCE_BROADCAST_CHANNEL_FIELD_DESC}}",
                    name: 'broadcastChannel',
                    id: 'broadcastChannel',
                    allowBlank: false,
                    columns: 1,
                    items: [
                        { boxLabel: "{{i18n PLUGINS_PAGE_SUBSCRIBE_USER_SUBSCRIPTIONS_BROADCAST_CHANNEL_LABEL_MAIL}}", name: 'broadcastChannel', inputValue: 'MAIL' },
                        { boxLabel: "{{i18n PLUGINS_PAGE_SUBSCRIBE_USER_SUBSCRIPTIONS_BROADCAST_CHANNEL_LABEL_SITE}}", name: 'broadcastChannel', inputValue: 'SITE'}
                    ]
                }
            ]
        });
    },
    
    /**
     * Validate the form and create the subscription
     * @private
     */
    _validateForm: function()
    {
        if (!this._formPanel.isValid())
        {
            return;
        }
        var values = this._formPanel.getForm().getValues();
        let subscriptionId = values.id;
        let mode = Ext.isEmpty(subscriptionId) ? "create" : "edit";
        let broadcastChannels = values.broadcastChannel;
        let broadcastChannelsAsArray = Array.isArray(broadcastChannels) ? broadcastChannels : [broadcastChannels];
        let parameters = [];
        if (mode == "create")
        {
            let group = JSON.parse(values.group);
            let groupId = group.groupId + "#" + group.groupDirectory;
            parameters = [Ametys.getAppParameters().siteName, groupId, values.tag, values.frequency, values.day, values.hour, broadcastChannelsAsArray];
        }
        else
        {
            parameters = [subscriptionId, values.frequency, values.day, values.hour, broadcastChannelsAsArray];
        }
        
        Ametys.data.ServerComm.callMethod({
            role: "org.ametys.plugins.pagesubscription.dao.ForceTagSubscriptionsDAO",
            methodName: mode == "create" ? "forceGroupSubscription" : "editForceSubscription",
            parameters: parameters,
            callback: {
                handler: this._validateFormCB,
                scope: this,
                arguments: {
                    mode: mode
                }
            },
            errorMessage: true,
            waitMessage: true
        });
    },
    
    /**
     * Callback after creating the subscription
     * @param {Object} response The response
     * @param {Object[]} args The additional arguments
     * @private
     */
    _validateFormCB: function(response, args)
    {
        if (response.success)
        {
            var subscriptionTarget = {
                id: Ametys.message.MessageTarget.SUBSCRIPTION,
                parameters: {
                    id: response.subscription.id
                }
            };
            
            Ext.create("Ametys.message.Message", {
                type: args.mode == "create" ? Ametys.message.Message.CREATED : Ametys.message.Message.MODIFIED,
                targets: subscriptionTarget
            });
            
            this._box.close();
        }
        else
        {
            if (args.mode == "create" && response.type == "ALREADY_EXIST")
            {
                let groupLabel = this._box.down("#group").getReadableValue();
                let tagLabel = this._box.down("#tag").getReadableValue();
                
                Ametys.Msg.show({
                    title: "{{i18n PLUGINS_PAGE_SUBSCRIBE_USER_SUBSCRIPTIONS_FORCE_BUTTON_ADD}}",
                    msg: Ext.String.format("{{i18n PLUGINS_PAGE_SUBSCRIBE_USER_SUBSCRIPTIONS_FORCE_BUTTON_ADD_ALREADY_EXIST_ERROR}}", tagLabel, groupLabel),
                    buttons: Ext.Msg.OK,
                    icon: Ext.Msg.ERROR
                });
            }
            else
            {
                Ametys.Msg.show({
                    title: args.mode == "create" ? "{{i18n PLUGINS_PAGE_SUBSCRIBE_USER_SUBSCRIPTIONS_FORCE_BUTTON_ADD}}" : "{{i18n PLUGINS_PAGE_SUBSCRIBE_USER_SUBSCRIPTIONS_FORCE_BUTTON_EDIT}}",
                    msg: args.mode == "create" ? "{{i18n PLUGINS_PAGE_SUBSCRIBE_USER_SUBSCRIPTIONS_FORCE_BUTTON_ADD_ERROR}}" : "{{i18n PLUGINS_PAGE_SUBSCRIBE_USER_SUBSCRIPTIONS_FORCE_BUTTON_EDIT_ERROR}}",
                    buttons: Ext.Msg.OK,
                    icon: Ext.Msg.ERROR
                });
            }
        }
        
    },
    
    /**
     * Create the frequency combobox
     * @private
     */
    _getFrequencyCombobox: function()
    {
        var store = Ext.create('Ext.data.Store', {
             data : [
                 {name: 'INSTANT', label: '{{i18n PLUGINS_PAGE_SUBSCRIBE_USER_SUBSCRIPTIONS_FREQUENCY_LABEL_INSTANT}}'},
                 {name: 'DAILY', label: '{{i18n PLUGINS_PAGE_SUBSCRIBE_USER_SUBSCRIPTIONS_FREQUENCY_LABEL_DAILY}}'},
                 {name: 'WEEKLY', label: '{{i18n PLUGINS_PAGE_SUBSCRIBE_USER_SUBSCRIPTIONS_FREQUENCY_LABEL_WEEKLY}}'},
                 {name: 'MONTHLY', label: '{{i18n PLUGINS_PAGE_SUBSCRIBE_USER_SUBSCRIPTIONS_FREQUENCY_LABEL_MONTHLY}}'}
             ]
        });
        
        return Ext.create("Ext.form.field.ComboBox", {
            cls: 'ametys',
            style: 'margin-left: 5px',
            forceSelection: true,
            editable: false,
            triggerAction: 'all',
            queryMode: 'local',
            valueField: 'name',
            displayField: 'label',
            store: store,
            id: "frequency",
            name: "frequency",
            allowBlank: false,
            fieldLabel: "{{i18n PLUGINS_PAGE_SUBSCRIBE_USER_SUBSCRIPTIONS_FORCE_FREQUENCY_FIELD_LABEL}}",
            ametysDescription: "{{i18n PLUGINS_PAGE_SUBSCRIBE_USER_SUBSCRIPTIONS_FORCE_FREQUENCY_FIELD_DESC}}",
            listeners: {
                'change': Ext.bind(function(field) {
                    switch(field.getValue()) {
                        case "INSTANT":
                            this._box.down("#day").disable();
                            this._box.down("#hour").disable();
                            break;
                        case "DAILY":
                            this._box.down("#day").disable();
                            this._box.down("#hour").enable();
                            break;
                        default:
                            this._box.down("#day").enable();
                            this._box.down("#hour").enable();
                    }
                }, this)
            }
        });
    },
    
    /**
     * Get the day combobx
     * @private
     */
    _getDayCombobox: function()
    {
        var store = Ext.create('Ext.data.Store', {
             data : [
                 {name: '1', label: '{{i18n plugin.core:PLUGINS_CORE_WEEK_DAYS_MONDAY}}'},
                 {name: '2', label: '{{i18n plugin.core:PLUGINS_CORE_WEEK_DAYS_TUESDAY}}'},
                 {name: '3', label: '{{i18n plugin.core:PLUGINS_CORE_WEEK_DAYS_WEDNESDAY}}'},
                 {name: '4', label: '{{i18n plugin.core:PLUGINS_CORE_WEEK_DAYS_THURSDAY}}'},
                 {name: '5', label: '{{i18n plugin.core:PLUGINS_CORE_WEEK_DAYS_FRIDAY}}'},
                 {name: '6', label: '{{i18n plugin.core:PLUGINS_CORE_WEEK_DAYS_SATURDAY}}'},
                 {name: '7', label: '{{i18n plugin.core:PLUGINS_CORE_WEEK_DAYS_SUNDAY}}'},
             ]
        });
        
        return Ext.create("Ext.form.field.ComboBox", {
            cls: 'ametys',
            style: 'margin-left: 5px',
            forceSelection: true,
            editable: false,
            triggerAction: 'all',
            queryMode: 'local',
            valueField: 'name',
            displayField: 'label',
            store: store,
            id: "day",
            name: "day",
            allowBlank: false,
            fieldLabel: "{{i18n PLUGINS_PAGE_SUBSCRIBE_USER_SUBSCRIPTIONS_FORCE_DAY_FIELD_LABEL}}",
            ametysDescription: "{{i18n PLUGINS_PAGE_SUBSCRIBE_USER_SUBSCRIPTIONS_FORCE_DAY_FIELD_DESC}}"
        });
    },
    
    /**
     * Edit the force subscription
     * @param {Ametys.ribbon.element.ui.ButtonController} controller The controller calling this function.
     */
    editForceSubscription: function(controller)
    {
        var subscriptionTarget = controller.getMatchingTargets()[0];
        var params = subscriptionTarget.getParameters();
        
        Ametys.data.ServerComm.callMethod({
            role: "org.ametys.plugins.pagesubscription.dao.ForceTagSubscriptionsDAO",
            methodName: "getSubscription",
            parameters: [params.id],
            callback: {
                handler: this._editSubscriptionCB,
                scope: this
            },
            errorMessage: true,
            waitMessage: true
        });
    },
    
    /**
     * Callback after editing the subscription
     * @param {Object} response The response
     * @private
     */
    _editSubscriptionCB: function(response)
    {
        if (response.success)
        {
            let subscription = response.subscription;
            
            this._createSubscriptionDialog();
            
            this._formPanel.reset();
            
            this._box.down("#id").setValue(subscription.id);
            this._box.down("#group").setValue(subscription.group.id + "#" + subscription.group.groupDirectory);
            this._box.down("#group").disable();
            this._box.down("#tag").setValue(subscription.tag.name);
            this._box.down("#tag").disable();
            this._box.down("#frequency").setValue(subscription.frequency.name);
            this._box.down("#broadcastChannel").setValue({broadcastChannel: subscription.broadcastChannel.map(c => c.name)})
            this._box.down("#day").setValue(subscription.forcedDay);
            this._box.down("#hour").setValue(subscription.forcedHour);
            this._box.show();
        }
        else
        {
            Ametys.Msg.show({
                title: "{{i18n PLUGINS_PAGE_SUBSCRIBE_USER_SUBSCRIPTIONS_FORCE_BUTTON_GET}}",
                msg: "{{i18n PLUGINS_PAGE_SUBSCRIBE_USER_SUBSCRIPTIONS_FORCE_BUTTON_GET_ERROR}}",
                buttons: Ext.Msg.OK,
                icon: Ext.Msg.ERROR
            });
        }
    },
    
    /**
     * Delete the subscription
     * @param {Ametys.ribbon.element.ui.ButtonController} controller The controller calling this function.
     */
    deleteSubscription: function(controller)
    {
        var subscriptionTarget = controller.getMatchingTargets()[0];
        var params = subscriptionTarget.getParameters();
        
        Ametys.Msg.confirm(
            "{{i18n PLUGINS_PAGE_SUBSCRIBE_USER_SUBSCRIPTIONS_FORCE_DELETE_CONFIRM_TITLE}}", 
            "{{i18n PLUGINS_PAGE_SUBSCRIBE_USER_SUBSCRIPTIONS_FORCE_DELETE_CONFIRM_MSG}}", 
            function(btn) {
                if (btn == 'yes')
                {
                    Ametys.data.ServerComm.callMethod({
                        role: "org.ametys.plugins.pagesubscription.dao.ForceTagSubscriptionsDAO",
                        methodName: "unsubscribe",
                        parameters: [params.id],
                        callback: {
                            handler: this._deleteSubscriptionCB,
                            scope: this,
                            arguments: {
                                id: params.id
                            }
                        },
                        errorMessage: true,
                        waitMessage: true
                    });
                }
            },
            this
        );
    },
    
    /**
     * Callback after deleting the subscription
     * @param {Object} response The response
     * @param {Object[]} args The additional arguments
     * @private
     */
    _deleteSubscriptionCB: function(response, args)
    {
        if (response)
        {
            var subscriptionTarget = {
                id: Ametys.message.MessageTarget.SUBSCRIPTION,
                parameters: {
                    id: args.id
                }
            };
            
            Ext.create("Ametys.message.Message", {
                type: Ametys.message.Message.DELETED,
                targets: subscriptionTarget
            });
        }
        else
        {
            Ametys.Msg.show({
                title: "{{i18n PLUGINS_PAGE_SUBSCRIBE_USER_SUBSCRIPTIONS_FORCE_BUTTON_DELETE}}",
                msg: "{{i18n PLUGINS_PAGE_SUBSCRIBE_USER_SUBSCRIPTIONS_FORCE_BUTTON_DELETE_ERROR}}",
                buttons: Ext.Msg.OK,
                icon: Ext.Msg.ERROR
            });
        }
        
    }
});