/*
 *  Copyright 2022 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 tool allows to see entries of a form.
 */
Ext.define('Ametys.plugins.forms.tool.EntriesSearchTool', {
    extend: 'Ametys.plugins.cms.search.AbstractSearchTool',
    
    /**
     * @private
     * @property {String} _formId The id of the form in the tool
     */
     
     /**
     * @private
     * @property {Boolean} _queueEnabled True is the queue is enabled for current form
     */
     
    constructor: function(config)
	{
		this.callParent(arguments);
		Ametys.message.MessageBus.on(Ametys.message.Message.DELETED, this.refresh, this);
		Ametys.message.MessageBus.on(Ametys.message.Message.WORKFLOW_CHANGED, this.refresh, this);
	},
	
	getMBSelectionInteraction: function()
    {
        return Ametys.tool.Tool.MB_TYPE_ACTIVE;
    },
	
	refresh: function()
    {
        this.callParent(arguments);
        
        var targets = Ametys.message.MessageBus.getCurrentSelectionMessage().getTargets(Ametys.message.MessageTarget.FORM_TARGET);
		if (!targets || targets.length == 0)
        {
            return;
        }
        
        this._queueEnabled = targets[0].getParameters().isQueueEnabled || false;
        this.setTitle(this.getInitialConfig("title") + " " + targets[0].getParameters().title);
    },
	
    _possiblyCallInternalSetParams: function()
    {
        var params = this.getParams();
        if (!this._formId || this._formId != params.formId)
        {
            this._formId = params.formId;
            this.setTitle(this.getInitialConfig("title") + " " + params.label)
        }
        else
        {
            this._paramsHasChanged = false;
            this._initSearchForm(params);
        }
        
        this._internalSetParams(false);
    },
    
    _getStoreCfg: function()
    {
        var config = {
            remoteSort: true,
            proxy: {
                type: 'ametys',
                plugin: 'forms',
                url: 'form/entries.json',
                cancelOutdatedRequest: true,
                reader: this._getReaderCfg()
             },
             sortOnLoad: true,
             listeners: {
                 'beforeload': {fn: this._onBeforeLoad, scope: this},
                 'load': {fn: this._onLoad, scope: this}
             }
        };
        
        if (this._queueEnabled)
        {
            config.groupField = 'ametys-queue-status';
        }
        
        return config;
    },

    _getReaderCfg: function()
    {
        return {
        	type: 'json',
            rootProperty: 'entries'
        };
    },
    
    _onSelectionChanged: function(sm, selected)
    {
        var button = this.searchPanel.down('#import-btn');
        if (button != null)
        {
            Ext.Array.filter(selected, function(record) {return record.get('imported') == false;}).length > 0 ? button.enable() : button.disable();
        }
        this.sendCurrentSelection();
    },
    
    getMBSelectionInteraction: function() 
    {
        return Ametys.tool.Tool.MB_TYPE_ACTIVE;
    },
	
	_getResultGridCfg: function(store)
    {
        var config = this.callParent(arguments);
        config.viewConfig = {
            loadingText: "{{i18n plugin.cms:UITOOL_SEARCH_WAITING_MESSAGE}}",
            getRowClass: function(record) {
                return record.get("ametys-active") ? '' : 'inactive';
            }
        }
        
        return config;
    },
	
	sendCurrentSelection : function()
	{
		var selection = this.grid.getSelectionModel().getSelection();
		var target = {
			id: Ametys.message.MessageTarget.FORM_TARGET,
			parameters: {
				id: this._formId,
				hasEntries: this.grid.getStore().getData().items.length > 0 ? true : false
			}
		};
		
		if(selection.length > 0){
	        var currentRecord = selection[0].getData();
        	target.subtargets = {
        		id: Ametys.message.MessageTarget.FORM_ENTRY,
	            parameters: { 
	                id: currentRecord["ametys-entryId"],
					formId: this._formId,
	                selection: this._previousSelection || null
	            }
        	};
		}
        Ext.create("Ametys.message.Message", {
			type: Ametys.message.Message.SELECTION_CHANGED,
			targets: target
		});
	},
    
    _retrieveCriteriaAndColumns: function(force)
    {
        this._updatingModel = true;
        
        Ametys.data.ServerComm.callMethod({
        	role: "org.ametys.plugins.forms.dao.FormEntryDAO",
        	methodName: "getSearchModelConfiguration",
            parameters: [this._formId],
        	callback: {
        		handler: this._getModelCb,
        		scope: this
        	},
            errorMessage: {
                msg: "{{i18n plugin.cms:UITOOL_SEARCH_ERROR}}",
                category: Ext.getClassName(this)
            }
        });
    },
    
    /**
     * @protected
     * Callback function after retrieving from server the search criteria and columns
     * @param {Object} result The server result
     */
    _getModelCb: function(result)
    {
        var toolParams = this.getParams().toolParams || {};
        this._configureSearchTool(result['criteria'], result, toolParams);
    },
    
    /**
     * Function called before loading the store
     * @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
     * @private
     */
    _onBeforeLoad: function(store, operation)
    {
        if (this.grid && !this._updatingModel && (!(this.form instanceof Ametys.form.ConfigurableFormPanel) ||  this.form.isFormReady()))
        {
            this.grid.getView().unmask();
            
            if (!this.form.isValid())
            {
                this._stopSearch();
                return false;
            }
            
            operation.setParams( Ext.apply(operation.getParams() || {}, {
                formId: this._formId,
    			values: this.form.getJsonValues()
            }));
            
            this._error = null;
        }
        else
        {
            // avoid use less requests at startup (applyState...)
            return false;
        }
    },
    
    /**
     * Function called after loading results
     * @param {Ext.data.Store} store The store
     * @param {Ext.data.Model[]} records An array of records
     * @param {Boolean} successful True if the operation was successful.
     * @param {Ext.data.Operation} operation The operation that triggered this load.
     * @private
     */
    _onLoad: function (store, records, successful, operation)
    {
        if (operation.aborted)
        {
            // the load has been canceled. Do nothing.
            return;
        }
        
    	// Hack to process groups locally even if remoteSort is enabled.
        store.getData().setAutoGroup(true);
        
        this._setGridDisabled(false);
        
        if (!successful)
        {
            Ametys.log.ErrorDialog.display({
                title: "{{i18n plugin.cms:UITOOL_SEARCH_ERROR_TITLE}}",
                text: "{{i18n plugin.cms:UITOOL_SEARCH_ERROR}}",
                details: "",
                category: "Ametys.plugins.forms.tool.EntriesSearchTool"
            });
            return;
        }
        
        if (this._error)
        {
            Ametys.log.ErrorDialog.display({
                title: "{{i18n plugin.cms:UITOOL_SEARCH_ERROR_QUERY_TITLE}}",
                text: this._error,
                details: "",
                category: "Ametys.plugins.forms.tool.EntriesSearchTool"
            });
        }
        
        if (records.length == 0)
        {
            this.grid.getView().mask("{{i18n plugin.cms:UITOOL_CONTENTEDITIONGRID_NO_RESULT}}", 'ametys-mask-unloading');
        }
        
        var targets = Ametys.message.MessageBus.getCurrentSelectionMessage().getTargets(Ametys.message.MessageTarget.FORM_ENTRY);
        if (targets && targets.length > 0)
        {
            var entryId = targets[0].getParameters().id;
            var record = this.store.findRecord("entryId", entryId);
            if (record)
            {
                this.grid.getSelectionModel().select(record);
            }
        }
    },
	
	createPanel: function()
	{
		var panel = this.callParent(arguments);
        
        // Search form not available in this tool
		this.searchPanel.hide();
        
		return panel;
	},
	
	/**
	 * Listener on deletion messages
	 * @param {Ametys.message.Message} message The deletion message.
	 * @private
	 */
	_onDeletionMessage: function (message)
	{
		var targets = message.getTargets(Ametys.message.MessageTarget.FORM_ENTRY);
		if (targets.length > 0)
		{
		 	var ids = Ext.Array.map(targets, function(target) {
                return this.grid.getStore().findExact('entryId', target.getParameters().id);
            }, this);
            this.grid.getStore().remove(ids);
        }
	},
});

Ext.define("Ametys.message.FormMessageTarget", {
	override: "Ametys.message.MessageTarget",
	
	statics: 
	{
		/**
		 * @member Ametys.message.MessageTarget
		 * @readonly
		 * @property {String} FORM_ENTRY The target type is a entry of a content's form. Parameters are:
		 * @property {Number} FORM_ENTRY.id The identifier of the entry
		 * @property {String} FORM_ENTRY.form The identifier of the parent form
		 */
		FORM_ENTRY: "form-entry"
	}
});