/*
 *  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 used to select a MCC modalite filtered by regime.
 */
Ext.define('Ametys.plugins.odfpilotage.widget.MccModalite', {
    extend : 'Ametys.cms.form.widget.SelectReferenceTableContent',
    
    statics: {
        /**
         * Listener for Ametys.form.Widget.onRelativeValueChange defined in the widget-params "changeListeners"
         * @param {String} event The event name configured
         * @param {String} relativePath The associated relativePath
         * @param {Ext.form.Field/Object} data The field or data. See Ametys.form.Widget#onRelativeValueChange
         * @param {Object} newValue The new value
         * @param {Object} oldValue The value before change
         */
        onRelativeValueChange: function(event, relativePath, data, newValue, oldValue)
        {
            if (event == 'regime')
            {
                if (data.isComponent)
                {
                    data._onRegimeFieldChange(relativePath, newValue, oldValue)
                }
                else
                {
                    if (newValue)
                    {
                        // Loop on all possible "fields" in the record following the path that can lead to repeaters
                        let mccModalityIds = Ametys.form.Widget.getRecordValues(data.record, data.dataPath);
                        for (let path of Object.keys(mccModalityIds))
                        {
                            let mccModalityId = mccModalityIds[path];
                            if (mccModalityId)
                            {
                                Ametys.plugins.odfpilotage.widget.MccModalite._getCompatibleRegimes(mccModalityId, function(compatibleRegimes) {
                                    if (compatibleRegimes.length != 0 
                                        && !Ext.Array.contains(compatibleRegimes, newValue))
                                    {
                                        // reset
                                        Ametys.form.Widget.setRecordValue(path, data.record, null);
                                    }
                                });
                            }
                        }
                    }
                }
            }
            else 
            {
                return false; // event not supported
            }
        },
        
        /**
         * @private
         * @property {Object} _compatibleRegimeseCache The cache for compatible regimes
         */
        _compatibleRegimeseCache: {},
        
        /**
         * @private 
         */
        _getCompatibleRegimes: function(mccModalityId, callback)
        {
            if (Ametys.plugins.odfpilotage.widget.MccModalite._compatibleRegimeseCache[mccModalityId] === undefined)
            {
                Ametys.data.ServerComm.callMethod({
                    role: "org.ametys.plugins.odfpilotage.helper.PilotageHelper",
                    methodName: "getCompatibleRegimes",
                    parameters: [mccModalityId],
                    callback: {
                        handler: function (compatibleRegimes) {
                            
                            Ametys.plugins.odfpilotage.widget.MccModalite._compatibleRegimeseCache[mccModalityId] = compatibleRegimes;
                            callback(Ametys.plugins.odfpilotage.widget.MccModalite._compatibleRegimeseCache[mccModalityId]);
                        },
                        scope: this
                    }
                });
            }
            else
            {
                callback(Ametys.plugins.odfpilotage.widget.MccModalite._compatibleRegimeseCache[mccModalityId]);
            }
        }
    },
    
    modelId: "search-ui.mcc-modalities",
    
    /**
     * @cfg {String} [regimeFieldPath=../mccRegime] The relative field path of MCC regime field
     */
     
    /**
     * @cfg {String} [compatibleRegimesCriterionId=compatibleRegimes] The id of the criterion for searching the compatible regimes. 
     */
    compatibleRegimesCriterionId: 'compatibleRegimes',
    
    
    /**
     * Filter modalite when regime changes in the form.
     * @private
     */
    _onRegimeFieldChange: function(relativePath, newValue, oldValue)
    {
        let me = this;
        
        this._currentMccRegime = newValue;
        
        var mccModalityId = this.getValue();
        if (mccModalityId)
        {
            if (this._currentMccRegime)
            {
                Ametys.plugins.odfpilotage.widget.MccModalite._getCompatibleRegimes(mccModalityId, function(compatibleRegimes) {
                    me._updateField(compatibleRegimes);
                });
            }
        }
        else
        {
            // Reset the last query to allow store to be reload on trigger click !
            this.combobox.lastQuery = undefined;
            this.combobox.getStore().removeAll();
        }
    },
    
    /**
     * @private
     * Update field when regime has changed
     * Reset the value and store of this field is value is no more compatible
     * @param {String[]} compatibleRegimes The server response
     */
    _updateField: function(compatibleRegimes)
    {
        // Reset the last query to allow store to be reload on trigger click !
        this.combobox.lastQuery = undefined;
        
        if (compatibleRegimes.length != 0 
            && !Ext.Array.contains(compatibleRegimes, this._currentMccRegime))
        {
            // current value is no more compatible, reset value and store
            this.setValue(null);
            this.combobox.getStore().removeAll();
        }
    },
    
    _onStoreBeforeLoad: function(store, operation)
    {
        this.callParent(arguments);
        
        var values = operation.getParams().values || {};
        
        if (this._currentMccRegime)
        {
            values[this.compatibleRegimesCriterionId] = this._currentMccRegime;
        }
      
        operation.setParams( Ext.apply(operation.getParams(), {
            values: values
        }));
    },
    
    /**
     * Get the value as single from the field, even if it is synchronized.
     * @private
     */
    _getSingleValueFromField: function(field)
    {
        // At initialization, field.getValue() can return null whereas field.value is not empty,
        // because degree field is initialized asynchronously.
        // Note that field.value can be an invalid or unknow id but it will be filtered by #getMentionContentTypes call
        var value = field.getValue() || field.value;
        // in case of externalizable field
        value = Ametys.form.widget.Externalizable.getValueInUse(value);
        // Get the first value, should be unique because it is a single field
        value = Ext.isArray(value) ? value : (Ext.isEmpty(value) ? [] : [value]);
        value = value.length > 0 ? value[0] : null;
        return value;
    }
});