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

 /**
  * MCC course tree grid panel
  * @private
  */
Ext.define('Ametys.plugins.odf.pilotage.tool.ContentViewTreeGridPanel', {
	extend: 'Ametys.plugins.odf.tree.AbstractODFTreeGridPanel',
    
    mixins: {
        editContentsView: "Ametys.cms.content.EditContentsView"
    },
    
    /**
     * @config {String} searchModel The name of the search model to determin columns
     */

    /**
     * @cfg {String} [messageTarget=Ametys.message.MessageTarget#CONTENT] The message target factory role to use for the event of the bus thrown and listened by the grid
     */
    
    constructor: function(config)
    {
        config.columns = [{ xtype: 'treecolumn', locked: true }/*this._getDefaultGridConfig()*/];
        config.methodArguments = ['contentId', 'path', 'tree', 'searchModel'];
        config.messageTarget = config.messageTarget || Ametys.message.MessageTarget.CONTENT;
        
        config.cls = Ext.Array.from(config.cls);
        config.cls.push("contentviewtreegrid");
        config.cls.push("treegrideditionfirst");

        this.callParent(arguments);
        
        config.saveBarPosition = 0;
        this.mixins.editContentsView.constructor.call(this, config);

        this.getStore().on('beforeload', function(store, operation) {
            if (operation.node.get('contentId'))
            {
                var params = Ext.apply(operation.getParams() || {}, {
                    'searchModel':  this.searchModel
                });
                operation.setParams(params);
            }
        }, this);
        this.getStore().on('load', this._onLoad, this);     
    },
    
    getContentRootNodeParameters: function(contentId, otherConfig)
    {
        let parameters = this.callParent(arguments);
        parameters.push(this.searchModel);
        return parameters;
    },
    
    _getNodeInformationsParameters(node)
    {
        let info = this.callParent(arguments);
        info.push(this.searchModel);
        return info;
    },    
    
    _onLoad: function(store, records, successful, operation, eOpts)
    {
        // Checking if the new record is not about an existing record with the same contentId
        let modifiedContents = {}
        for (let modifiedRecord of this.store.getModifiedRecords()) // Maybe we should use this.getModifiedRecords() (from EditContentsView) to also include rootNode  
        {
            modifiedContents[this._getContentId(modifiedRecord)] = modifiedRecord;
        }
        for (let record of records)
        {
            this._loadRecord(record, modifiedContents);
        }
    },
    
    _onRootNodeLoad: function(record)
    {
        // root node does not trigger the classical load event
        this._loadRecord(record, []);
    },
    
    _loadRecord: function(record, modifiedContents) 
    {
        if (record.data.data)
        {
            let modifiedRecord = modifiedContents[this._getContentId(record)];
            let changes;
            if (modifiedRecord)
            {
                changes = modifiedRecord.getChanges();
            }
            
            let changesKeys = changes ? Object.keys(changes) : null;
            if (changesKeys)
            {
                for (let changeFieldName of changesKeys)
                {
                    if (modifiedRecord.get(changeFieldName + "_repeater") !== undefined)
                    {
                        changes[changeFieldName + "_repeater"] = modifiedRecord.get(changeFieldName + "_repeater");
                    }
                    if (modifiedRecord.get(changeFieldName + "_content") !== undefined)
                    {
                        changes[changeFieldName + "_content"] = modifiedRecord.get(changeFieldName + "_content");
                    }
                }
                changesKeys = Object.keys(changes);
            }
            
            let dataKeys = Object.keys(record.data.data);
            
            for (let k of dataKeys)
            {
                if (!changesKeys || !changesKeys.includes(k))
                {
                    // Any initial must be reset before setting the new loaded value
                    for (let k2 of Object.keys(record.data))
                    {
                        if (k2.startsWith(k + "_")
                            && k2.endsWith("_initial"))
                        {
                            delete record.data[k2];
                        }
                    }
                    
                    record.set(k, record.data.data[k], {silent: true});
                }
            }
            record.set('data', undefined, {silent: true});
            record.set('editionAvailable', true, {silent: true});
            record.commit(false, Object.keys(record.modified)); // specifying the list of modified items avoid a basic refresh of the title cell that destroy the decorators
            
            if (changesKeys)
            {
                for (let changeFieldName of changesKeys)
                {
                    record.set(changeFieldName, changes[changeFieldName]);
                }
            }
        }
        
        let me = this;
        window.setTimeout(function() {
            for (let childRecord of record.childNodes || [])
            {
                me._loadRecord(childRecord, modifiedContents);
            }
        }, 1)
    },
    
    /**
     * Function creating the structure of the columns grid 
     * @private
     */
    _getDefaultGridConfig: function()
    {
        return [
            {
                xtype: 'treecolumn',
                text: "{{i18n plugin.cms:PLUGINS_CMS_METADATA_TITLE_LABEL}}",
                stateId: 'title',
                sortable: false,
                dataIndex: 'title',
                width: 400,
                locked: true,
                lockable: false
            }
        ];
    },
    
    _createEditPlugin: function(config) {
        let plugin = this.mixins.editContentsView._createEditPlugin.apply(this, arguments);
        plugin.editAfterSelect = false;
        return plugin;
    },
    
    _getContentId(record) {
        return record.get('contentId');
    },
    
    _findRecords(contentId) {
        let records = [];
        
        // Using byIdMap allow to search even in filtered items
        for (let id in this.store.byIdMap)
        {
            if (this.store.byIdMap[id].get('contentId') == contentId)
            {
                records.push(this.store.byIdMap[id]);
            }
        }
        
        return records;
    },
    
    _sendMessages: function()
    {
        let toolRootCmp = this.ownerCt;
        while (!toolRootCmp.uiTool)
        {
            toolRootCmp = toolRootCmp.ownerCt;
        } 
        
        let toolId = toolRootCmp.uiTool;
        let tool = Ametys.tool.ToolsManager.getTool(toolId) 
        tool._ignoreNextModified++;
        
        this.mixins.editContentsView._sendMessages.apply(this, arguments);
    }
});