/*
 *  Copyright 2023 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 to edit MCC in course 
 * @private
 */
Ext.define('Ametys.plugins.odf.pilotage.tool.MCCCourseTool', {
    extend: 'Ametys.plugins.odf.pilotage.tool.ContentViewTreeGridTool',
   
    statics: {
        /**
         * @private
         * Fill a cache object with the table ref data
         */
        _getTableRefData: function(tableRefId, cache) {
            Ametys.data.ServerComm.send({
                plugin: 'cms',
                url: 'search/list.json',
                parameters: {
                    model: tableRefId
                },
                priority: Ametys.data.ServerComm.PRIORITY_MAJOR,
                errorMessage: true,
                callback: {
                    handler: function(response) {
                        if (Ametys.data.ServerComm.isBadResponse(response))
                        {
                            return;
                        }
                        
                        let result = Ext.JSON.decode(Ext.dom.Query.selectValue("", response));
                        for (let c of result.contents)
                        {
                            cache[c.id] = {
                                title: Ametys.plugins.cms.search.SearchGridHelper.getDefaultLocalizedValue(c.title),
                                shortLabel: c.properties.shortLabel
                            };
                        }
                    },
                    scope: this,
                },
                responseType: 'text'
            });
        },
        
        /**
         * @private
         * @property {Object} _natureCache The internal reftable cache 
         */
        _natureCache: {},
        
        /**
         * @private
         * @property {Object} _regimeCache The internal reftable cache 
         */
        _regimeCache: {},
        
        /**
         * @private
         * @property {Object} _modalite2Cache The internal reftable cache 
         */
        _modaliteCache: {},
        
        /**
         * @private
         * @property {Ext.XTemplate} _repeaterTpl The template used for rendering repeater entries
         */
        _repeaterTpl: Ext.create('Ext.XTemplate', [
            '<span data-qtip="{tip}"><tpl for="entries">',
                '<tpl if="position &gt; 1">',
                    ", ",
                '</tpl>',
                '<span class="a-grid-repeater-entry">{label}</span>',
            '</tpl></span>'
        ]),
        
        renderTrueWhenNull: function(value, metaData, record, rowIndex, colIndex, store, view, dataIndex)
        {
            let v = value;
            if ((v === undefined || v == null)
                && (record.get('contenttypesIds') || []).includes('org.ametys.plugins.odf.Content.course'))
            {
                v = true;
            }
            return Ametys.grid.GridColumnHelper.renderBooleanIcon(v, metaData, record, rowIndex, colIndex, store, view, dataIndex)
        },
        
        renderTrueWhenNullInRepeater: function(value, metaData, record, rowIndex, colIndex, store, view, dataIndex)
        {
            let v = value;
            if (v === undefined || v == null)
            {
                v = true;
            }
            return Ametys.grid.GridColumnHelper.renderBooleanIcon(v, metaData, record, rowIndex, colIndex, store, view, dataIndex)
        },

        renderMCCRegime: function(value, metaData, record, rowIndex, colIndex, store, view, dataIndex)
        {
            return this._readShortLabelOrTitle(record.data, "mccRegime", Ametys.plugins.odf.pilotage.tool.MCCCourseTool._regimeCache, "");
        },
        
        /**
         * @private
         * Get the short label if available in cache, title otherwise
         */
        _readShortLabelOrTitle(values, dataindex, cache, otherwise)
        {
            if (values[dataindex])
            {
                let cacheEntry = cache[values[dataindex]];
                if (cacheEntry)
                {
                    return cacheEntry.shortLabel || cacheEntry.title;
                }
                else
                {
                    return values[dataindex + "_content"][values[dataindex]].title;
                }
            }
            else
            {
                return otherwise;
            }
        },
        
        renderRepeater: function(value, metaData, record, rowIndex, colIndex, store, view, dataIndex)
        {
            let me = this;
            
            let repeater = record.get(dataIndex + "_repeater") || record.get(dataIndex);
            let rawValues = repeater ? repeater.entries : null;

            let knownEducationalPath = record.getPath("contentId", ";").substring(1);
            let matchingEducationalPaths = record.get("educationalPaths");

            if (matchingEducationalPaths.length == 1)
            {
                let currentEducationalPath = matchingEducationalPaths[0].path;
                let currentEducationalPathLabel = matchingEducationalPaths[0].label;
                
                // VERY IMPORTANT remmeber the educational path selected to allow the widget edit the record later
                let repData = record.get(dataIndex + "_repeater"); 

                repData._educationalPath = repData._educationalPath || {};
                repData._educationalPath[record.getId()] = currentEducationalPath;
                
                repData._educationalPathLabel = repData._educationalPathLabel || {};
                repData._educationalPathLabel[record.getId()] = currentEducationalPathLabel;

                if (Ext.isEmpty(value) || !Ext.isObject(repeater) || !Ext.isArray(rawValues) || rawValues.length == 0)
                {
                    return '';
                }

                let rawByPathValues = rawValues.filter(a => a.values.common !== false || a.values.path == currentEducationalPath);

                return display(rawByPathValues);
            }
            else 
            {
                // Truncate the educational path to the meaningful part
                let nbItemsToRemove = (knownEducationalPath.match(/;/g) || []).length + 1;

				rawValues = Ext.Array.from(rawValues);
                
                let rawByPathValues = rawValues.filter(a => a.values.common !== false);
                let onlyGlobalValue = rawByPathValues.length == rawValues.length;
                
                if (!onlyGlobalValue)
                {
                    cellIsNotEditable();
                    
                    // Not clickable when not editable (whereas by default repeaters are)           
                    record.data.notClickableRepeater = record.data.notClickableRepeater || [];
                    record.data.notClickableRepeater.push(dataIndex);
                }
                else
                {
                    // VERY IMPORTANT remmeber the educational path selected to allow the widget edit the record later
                    let repData = record.get(dataIndex + "_repeater"); 

                    repData._educationalPathLabel = repData._educationalPathLabel || {};
                    repData._educationalPathLabel[record.getId()] = record.getPath("title", " > ").substring(3);
                    
                    let rootsLabels = [];
                    for (let matchingEducationalPath of matchingEducationalPaths)
                    {
                        let labelParts = matchingEducationalPath.label.split(" > ");
                        
                        let meaningFullLabelParts = labelParts.slice(0, labelParts.length - nbItemsToRemove);
                        let meaningFullHtmlParts = [];
                        for (let i=0; i < meaningFullLabelParts.length; i++)
                        {
                            meaningFullHtmlParts.push(meaningFullLabelParts[i]);
                        }  
                        
                        let label = meaningFullHtmlParts.join(" > ");
                        rootsLabels.push(label);
                        
                        repData._educationalPathRootLabels = repData._educationalPathRootLabels || {};
                        repData._educationalPathRootLabels[record.getId()] = rootsLabels;
                    }
                }
                
                if (!onlyGlobalValue)
                {
                    let qTip = "{{i18n PLUGINS_ODF_PILOTAGE_RIGHTS_MCCCOURSE_MCCSESSIONS_EDUCATIONAL_PATH_MULTIPLE_MIXED_TOOLTIP_INTRO}}";
                                
                    qTip += "<ul style=\'margin: 0 5px 0 5px; padding: 0 0 0 20px;\'>";
                    for (let matchingEducationalPath of matchingEducationalPaths)
                    {
                        let labelParts = matchingEducationalPath.label.split(" > ");
                        let idParts = matchingEducationalPath.path.split(";");
                        
                        let meaningFullLabelParts = labelParts.slice(0, labelParts.length - nbItemsToRemove);
                        let meaningFullHtmlParts = [];
                        for (let i=0; i < meaningFullLabelParts.length; i++)
                        {
                            let meaningFullLabelPart = meaningFullLabelParts[i];
                            let id = idParts[i];
                            
                            meaningFullHtmlParts.push("<a href='javascript:void(0)' onclick=&quot;Ametys.tool.ToolsManager.openTool('uitool-content', {id: '" + id + "'})&quot;>" + meaningFullLabelPart.replaceAll("\"", "&quot;") + "</a>");
                        }  
                        
                        let label = meaningFullHtmlParts.join(" > ");
                        
                        qTip += "<li style='margin: 5px 0 5px 0'>" + label + "</li>";
                    }
                    qTip += "</ul>";
    
                    metaData.tdAttr = "data-anchor='right' data-qtip=\"" + qTip + "\""
                }

				/*if (Ext.isEmpty(value) || !Ext.isObject(repeater) || rawValues.length == 0)
                {
                    return '';
                }*/
								
                return onlyGlobalValue ? display(rawByPathValues) : "{{i18n PLUGINS_ODF_PILOTAGE_RIGHTS_MCCCOURSE_MCCSESSIONS_EDUCATIONAL_PATH_MULTIPLE_MIXED_VALUE}}";
            }
            
            function cellIsNotEditable()
            {
                metaData.tdCls = metaData.tdCls.split(" ")
                                    .filter(x => !!x) // remove empty
                                    .map(x => x == "editable" ? "cell-noteditable" : x) // replace editable by noteditable
                                    .filter((x, index, array) => array.indexOf(x) === index) // distinct values
                                    .join(" ");
                record.data.notEditableDataIndex = record.data.notEditableDataIndex || [];
                record.data.notEditableDataIndex.push(dataIndex);
            }
                
            function display(rawValues)
            {
                let labels = [];
                
                // cannot rely on rawValues[x].position since they were filtered
                let x = 1;
                
                let entries = [];
                for (let i in rawValues)
                {
                    let rawValue = rawValues[i];
                    
                    let label = "";
                    
                    label += me._readShortLabelOrTitle(rawValue.values, "nature", Ametys.plugins.odf.pilotage.tool.MCCCourseTool._natureCache, "");
                    
                    label += " (";
    
                    label += me._readShortLabelOrTitle(rawValue.values, "modalite", Ametys.plugins.odf.pilotage.tool.MCCCourseTool._modaliteCache, "");
                    
                    if (rawValue.values["coefficient"])
                    {
                        label += ", Coef. " + rawValue.values["coefficient"];
                    }
    
                    label += ")";
    
                    
                    labels.push(label);
                    entries.push({
                        label: label,
                        position: x
                    });
                    
                    x++;
                }
                
                let html = me._repeaterTpl.applyTemplate({
                    entries: entries,
                    tip: labels.join(",<br/>")
                });
                
                return html;
            }
        },
        
        renderRepeaterByEducationalPath: function(value, metaData, record, rowIndex, colIndex, store, view, dataIndex)
        {
            metaData.tdCls += ' ftype-educationalPath';

            // Not clickable when not editable (whereas by default repeaters are)           
            record.data.notClickableRepeater = record.data.notClickableRepeater || [];
            record.data.notClickableRepeater.push(dataIndex);

            let repeater = record.get(dataIndex + "_repeater") || record.get(dataIndex);
            let rawValues = repeater ? repeater.entries : null;

            let knownEducationalPath = record.getPath("contentId", ";").substring(1);
            let matchingEducationalPaths = record.get("educationalPaths");
            
            if (matchingEducationalPaths.length == 1)
            {
                let currentEducationalPath = matchingEducationalPaths[0].path;
                
                // VERY IMPORTANT remember the educational path selected to allo the widget edit the record later
                let repData = record.get(dataIndex + "_repeater"); 
                repData._educationalPath = repData._educationalPath || {};
                repData._educationalPath[record.getId()] = currentEducationalPath;
                
                if (Ext.isEmpty(value) || !Ext.isObject(repeater) || !Ext.isArray(rawValues) || rawValues.length == 0)
                {
                    return '';
                }
                
                let rawByPathValues = rawValues.filter(a => a.values[(metaData.column.editor || metaData.column.field).pathField] == currentEducationalPath);
                if (rawByPathValues.length > 1)
                {
                    return 'ERROR'; // Not handled properly since a global validation is done to avoid this case
                }
                else 
                {
                    if (rawByPathValues.length == 0)
                    {
                        return '';
                    }
                    else
                    {
                        return rawByPathValues[0].values[(metaData.column.editor || metaData.column.field).valueField]; 
                    }
                }
            }
            else 
            {
                // Truncate the educational path to the meaningful part
                let nbItemsToRemove = (knownEducationalPath.match(/;/g) || []).length + 1;

                // Cell is not editable
                metaData.tdCls = metaData.tdCls.replace(/ editable(?= )/g, '') + ' cell-noteditable';
                record.data.notEditableDataIndex = record.data.notEditableDataIndex || [];
                record.data.notEditableDataIndex.push(dataIndex);
                
                if (Ext.isEmpty(value) || !Ext.isObject(repeater) || !Ext.isArray(rawValues) || rawValues.length == 0)
                {
                    return '';
                }

                let qTip = "{{i18n PLUGINS_ODF_PILOTAGE_RIGHTS_MCCCOURSE_REPEATER_EDUCATIONAL_PATH_MULTIPLE_TOOLTIP_INTRO}}";
                qTip += "<ul style=\'margin: 0 5px 0 5px; padding: 0 0 0 20px;\'>";
                for (let matchingEducationalPath of matchingEducationalPaths)
                {
                    let labelParts = matchingEducationalPath.label.split(" > ");
                    let idParts = matchingEducationalPath.path.split(";");
                    
                    let meaningFullLabelParts = labelParts.slice(0, labelParts.length - nbItemsToRemove);
                    let meaningFullHtmlParts = [];
                    for (let i=0; i < meaningFullLabelParts.length; i++)
                    {
                        let meaningFullLabelPart = meaningFullLabelParts[i];
                        let id = idParts[i];
                        
                        meaningFullHtmlParts.push("<a href='javascript:void(0)' onclick=&quot;Ametys.tool.ToolsManager.openTool('uitool-content', {id: '" + id + "'})&quot;>" + meaningFullLabelPart.replaceAll("\"", "&quot;") + "</a>");
                    }  
                    
                    let label = meaningFullHtmlParts.join(" > ");
					label += "<span style='white-space:nowrap;'> > … > </span>" + record.get('title');
                    
                    let rawByPathValues = rawValues ? rawValues.filter(a => a.values[(metaData.column.editor || metaData.column.field).pathField] == matchingEducationalPath.path) : [];
                    if (rawByPathValues.length == 1)
                    {
                        label += " ({{i18n PLUGINS_ODF_PILOTAGE_RIGHTS_MCCCOURSE_REPEATER_EDUCATIONAL_PATH_MULTIPLE_TOOLTIP_VALUE}} " + rawByPathValues[0].values[(metaData.column.editor || metaData.column.field).valueField] + ")";
                    }
                    else
                    {
                        label += " ({{i18n PLUGINS_ODF_PILOTAGE_RIGHTS_MCCCOURSE_REPEATER_EDUCATIONAL_PATH_MULTIPLE_TOOLTIP_NOVALUE}})";
                    }
                    
                    qTip += "<li style='margin: 5px 0 5px 0'>" + label + "</li>";
                }
                qTip += "</ul>";
                
                metaData.tdAttr = "data-anchor='left' data-qtip=\"" + qTip + "\""
                
                return "{{i18n PLUGINS_ODF_PILOTAGE_RIGHTS_MCCCOURSE_REPEATER_EDUCATIONAL_PATH_MULTIPLE_VALUE}}" ;
            }
        }
    },
    
    _createTree: function()
    {
        return Ext.create('Ametys.plugins.odf.pilotage.tool.MCCCourseTreeGridPanel', this._getTreeConfig());
    },
   
    _getColumnsCb: function(columnsData, args)
    {
        let columnsDataModified = columnsData.map(c => {
            if (c.type == "repeater" && (c.path == "mccSession1" || c.path == "mccSession2"))
            {
                c.widget = "edition.mcccourserepeater";
                c['widget-params'] = {
                    dataIndexes: ["mccSession1", "mccSession2"],
                    authorizeCopy: "reportSession2",
                    doNotCopy: ["modalite", "modalite_content", "modalite_content_initial"]
                };
                
                c.columns.filter(c => c.name == "notes").map(sc => { sc.widget = "edition.notesRepeaterAsForm"; sc["widget-params"] = {mode: "table"}; });
            } 
            else if (c.type == "repeater" && c.columns.length == 2 && c.columns.filter(cc => cc.type == 'educational-path').length == 1)
            {
                let pathColumn = c.columns.filter(col => col.type == 'educational-path')[0];
                let valueColumn = c.columns.filter(col => col != pathColumn)[0];
                
                c.widget = "edition.repeaterValueByEducationalPath";
                c['widget-params'] = c['widget-params'] || {};
                c['widget-params']['pathField'] = pathColumn.name;
                c['widget-params']['valueField'] = valueColumn.name;
                c['widget-params']['innerWidget'] = Ext.applyIf({
                    xtype: Ametys.form.WidgetManager.getWidgetXType(valueColumn.widget, valueColumn.type, !!valueColumn.enumeration, valueColumn.multiple), 
                    enumeration: valueColumn['enumeration'], 
                    multiple: valueColumn['multiple'],                     
                }, valueColumn['widget-params']);
            }
            
            return c;
        });
        
        this.callParent([columnsDataModified, args]);
    },
    
    _getTreeConfig: function()
    {
        var treeCfg = this.callParent(arguments);
        var activeIndicators = treeCfg.activeIndicators || [];
        activeIndicators.push("odf-pilotage-indicator-excluded-mcc-status");
        
        return Ext.apply(treeCfg, {
            forceReadonlyField: "mccSession2",
            activeIndicators: activeIndicators
        });
    }
}); 

// Fetch all renderer values
(function () {
    Ametys.plugins.odf.pilotage.tool.MCCCourseTool._getTableRefData('reference-table-search-ui.odf-enumeration.MccSessionNature', Ametys.plugins.odf.pilotage.tool.MCCCourseTool._natureCache);
    Ametys.plugins.odf.pilotage.tool.MCCCourseTool._getTableRefData('reference-table-search-ui.odf-enumeration.MccRegime', Ametys.plugins.odf.pilotage.tool.MCCCourseTool._regimeCache);
    Ametys.plugins.odf.pilotage.tool.MCCCourseTool._getTableRefData('reference-table-search-ui.odf-enumeration.MccModaliteSession1', Ametys.plugins.odf.pilotage.tool.MCCCourseTool._modaliteCache);
    Ametys.plugins.odf.pilotage.tool.MCCCourseTool._getTableRefData('reference-table-search-ui.odf-enumeration.MccModaliteSession2', Ametys.plugins.odf.pilotage.tool.MCCCourseTool._modaliteCache);
})();