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

/**
 * Tool that display the list of projects and their statistics
 * @private
 */
Ext.define('Ametys.plugins.workspaces.project.tool.StatisticsTool', {
    extend: 'Ametys.tool.Tool',
    
    
    constructor: function(config)
    {
        this.callParent(arguments);
        Ametys.message.MessageBus.on(Ametys.message.Message.MODIFIED, this._onMessageCreatedOrModified, this);
        Ametys.message.MessageBus.on(Ametys.message.Message.CREATED, this._onMessageCreatedOrModified, this);
        Ametys.message.MessageBus.on(Ametys.message.Message.DELETED, this._onMessageDeleted, this);
    },
        
    getMBSelectionInteraction: function() 
    {
        return Ametys.tool.Tool.MB_TYPE_ACTIVE;
    },
    
    createPanel: function()
    {
        
        Ametys.data.ServerComm.callMethod({
            role: "org.ametys.plugins.workspaces.project.ProjectManager",
            methodName: "getProjectsStatisticsColumnsModel",
            parameters: [],
            callback: {
                scope: this,
                handler: this._getStatisticHeadersCb
            },
            errorMessage: {
                category: this.self.getName(),
                msg: "{{i18n PLUGINS_WORKSPACES_DAOS_PROJECT_ERROR}}"
            }
        });
        
        this._panel = Ext.create('Ext.container.Container', {
            layout: 'fit',
            items: {
                xtype: "component",
                html: "{{i18n PLUGINS_WORKSPACES_PROJECT_STATISTICS_TOOL_LOADING}}"
            }
        })
        
        return this._panel;
    },
    
    /**
     * @private
     * Create fields from data
     * @param {Object} data The data
     */
    _getFieldsFromJson: function (data)
    {
        let fields = [];
        data.forEach(function (column) {
            if (column.subColumns)
            {
                let subFields = this._getFieldsFromJson(column.subColumns);
                fields = fields.concat(subFields);
            }
            else
            {
                field = { name: column.id, type: column.type };
                if (column.type == "date" || column.type == "datetime")
                {
                    field.dateFormat = Ext.Date.patterns.ISO8601DateTime;
                    field.type = "date";
                }
                if (column.type == "long")
                {
                    field.type = "int";
                }
                fields.push(field);
            }
        }, this);
        return fields;
    },
    
    /**
     * @private
     * Callback function called after #getStatisticHeaders is processed
     * @param {Object} data The project properties
     * @param {Array} args The callback arguments.
     */
    _getStatisticHeadersCb: function (data)
    {
        fields = this._getFieldsFromJson(data);
          
        //used for project renderer
        fields.push({ name: 'valid', type: 'boolean', defaultValue: true })

        let modelName = "Ametys.plugins.workspaces.project.tool.StatisticsTool.StatisticsEntry";
        
        if (!Ext.data.schema.Schema.get('default').hasEntity(modelName)) 
        {
            Ext.define(modelName, {
                extend: 'Ext.data.Model',
                schema: 'default',
                fields: fields
            });
        }
        
        this._store = Ext.create('Ext.data.Store', {
            model: modelName,
            proxy: {
                type: 'ametys',
                role: 'org.ametys.plugins.workspaces.project.ProjectManager',
                methodName: 'getProjectsStatisticsForClientSide',
                methodArguments: [],
                reader: {
                    type: 'json'
                }
            },
            autoLoad: true, 
            sorters: [{property: 'title', direction: 'ASC'}]
        });
        
        var columns = Ametys.plugins.cms.search.SearchGridHelper.getColumnsFromJson(data, true);
        
        this._grid = Ext.create('Ext.grid.Panel', {
            
            stateful: true,
            stateId: this.self.getName() + "$grid",
            plugins: ['gridfilters'],
            
            // Languages combo box
            dockedItems: [{
                dock: 'top',
                xtype: 'toolbar',
                layout: {
                    type: 'hbox',
                    align: 'stretch'
                },
                
                border: false,
                defaults : {
                    cls: 'ametys',
                    labelWidth: 55,
                    labelSeparator: ''
                },
                
                items: [{
                    // Search input
                    xtype: 'textfield',
                    itemId: 'search-filter-input',
                    cls: 'ametys',
                    flex: 1,
                    maxWidth: 300,
                    emptyText: "{{i18n PLUGINS_WORKSPACES_PROJECT_LIST_TOOL_FILTER_EMPTY_TEXT}}",
                    enableKeyEvents: true,
                    minLength: 3,
                    minLengthText: "{{i18n PLUGINS_WORKSPACES_PROJECT_LIST_TOOL_FILTER_MIN_LENGTH_INVALID}}",
                    msgTarget: 'qtip',
                    listeners: {change: Ext.Function.createBuffered(this._filterByTitle, 300, this)}
                }, {
                    // Clear filter
                    tooltip: "{{i18n PLUGINS_WORKSPACES_PROJECT_LIST_TOOL_FILTER_CLEAR}}",
                    handler: Ext.bind (this._clearFilter, this),
                    iconCls: 'a-btn-glyph ametysicon-eraser11 size-16',
                    cls: 'a-btn-light'
                }]
            }],
            
            store: this._store,
            
            selModel: {
                mode: 'SINGLE'
            },
            columns: columns
        });
        
        this._panel.removeAll();
        this._panel.add(this._grid);
    },
        
    /**
     * @private
     * Filters queries by input field value.
     * @param {Ext.form.Field} field The field
     */
    _filterByTitle: function (field)
    {
        var value = Ext.String.trim(field.getValue());
        if (this._filterValue == value)
        {
            // Do nothing
            return;
        }
        
        this._filterValue = value;
        var regexFilter = new RegExp(value, 'i');
        
        if (value.length > 2)
        {
            var currentSelection = this._grid.getSelection();
           
            this._store.clearFilter();
            this._store.filterBy(function(record){
                return regexFilter.test(record.data.title) || regexFilter.test(record.data.name);
            });
            
            if (currentSelection.length > 0)
            {
                var me = this;
                Ext.Array.each(currentSelection, function (sel) {
                    if (me._store.findExact(me._store.getModel().idProperty, sel.getId()) == -1)
	                {
	                    // The current selection is not visible, clear the selection
	                    me._grid.getSelectionModel().deselect([sel]);
	                }
                })
                
            }
        }
        else
        {
            // We do not call _clearFilter that will also empty the filter and prevent from typing
            this._filterValue = null;
            this._store.clearFilter(); 
        }
    },
    
    /**
     * Clear the current filter
     */
    _clearFilter: function()
    {
        this._grid.down("#search-filter-input").reset();
        this._filterValue = null;
        
        this._store.clearFilter();
    },
    
    setParams: function (params)
    {
        this.callParent(arguments);
        this.refresh();
    },
    
    /**
     * Refreshes the tool
     */
    refresh: function ()
    {
        // On the first launch, the store is not created yet. It will be loaded after creation.
        if(this._store)
        {
            this._store.load();
        }
    },
    
    /**
     * Listener on creation or edition message.
     * @param {Ametys.message.Message} message The edition message.
     * @private
     */
    _onMessageCreatedOrModified: function(message)
    {
        var targets = message.getTargets(Ametys.message.MessageTarget.WORKSPACES_PROJECT);
        if (targets.length > 0)
        {
            this.showOutOfDate();
        }
    },
    
    /**
     * Listener on deletion message.
     * @param {Ametys.message.Message} message The deletion message.
     * @private
     */
    _onMessageDeleted: function(message)
    {
        var targets = message.getTargets(Ametys.message.MessageTarget.WORKSPACES_PROJECT);
        for (var i = 0; i < targets.length; i++)
        {
            var record = this._store.getById(targets[i].getParameters().id);
            this._store.remove(record);
        }
    },
    
    sendCurrentSelection: function()
    {
    }
});