/*
 *  Copyright 2025 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 helper provides renderer for grid column.
 */
Ext.define("Ametys.grid.GridColumnHelper", {
    singleton: true,

    /**
     * Renderer for String that escape the characters using HTML entities, unless record contains a field 'config-doNotEscapeHtml' equals to <code>true</code>
     * @param {String|String[]} value The data value
     * @param {Object} metaData A collection of data about the current cell
     * @param {Ext.data.Model} record The record
     * @return {String} The escaped value to render.
     */
    renderWithHtmlEscaping: function(value, metadata, record)
    {
		if (!value || record.get('config-doNotEscapeHtml') === true)
		{
			return value;
		}
		
        if (Ext.isArray(value))
        {
            return Ext.Array.map(value, v => Ext.String.escapeHtml(v)).join(", ");
        }
        else
        {
	        return Ext.String.escapeHtml(value);
        }
    },
    
    
    /**
     * Renderer for a value to be preceded by a icon associated to the record.<br>
	 * Icon is search on 'iconGlyph' or 'iconCls' or 'icon' record's properties.<br>
	 * Text value is HTML escaped, unless record contains a field 'config-doNotEscapeHtml' equals to <code>true</code>.
     * @param {String} value the value to display
     * @param {Object} metadata A collection of metadata about the current cell
     * @param {Ext.data.Model} record The record for the current row
     * @return {String} The value preceded by the icon if exists
     */
    renderTextWithIcon: function(value, metadata, record)
    {
		var text = record.get('config-doNotEscapeHtml') !== true ? Ext.String.escapeHtml(value) : value;
		
        if (record.get('iconGlyph') != null)
        {
            return '<span class="a-grid-glyph ' + record.get('iconGlyph') + (record.get('iconDecorator') != null ? ' ' + record.get('iconDecorator') : '') + '"></span>' + text;
        }
        else if (record.get('iconCls') != null)
        {
            return '<span class="a-grid-glyph ' + record.get('iconCls') + '"></span>' + text;
        }
        else if (record.get('icon'))
        {
            return '<img src="' + Ametys.CONTEXT_PATH + record.get('icon') + '" class="a-grid-icon a-grid-icon-title"/>' + text;
        }
		else
		{
			return text; // No icon found
		}
    },
	
	/**
     * Function to render a boolean value as 'yes' or 'no' text
     * @param {Object} value The data value
     * @param {Object} metaData A collection of metadata about the current cell
     * @param {Ext.data.Model} record The record
     */
    renderBoolean: function (value, metaData, record)
    {
        var isTrue = Ext.isBoolean(value) ? value : value == 'true';
        if (isTrue)
        {
            return "{{i18n plugin.core-ui:PLUGINS_CORE_UI_GRID_COLUMN_BOOLEAN_YES}}";
        }
        else
        {
            return "{{i18n plugin.core-ui:PLUGINS_CORE_UI_GRID_COLUMN_BOOLEAN_NO}}";
        }
    },
    
    /**
     * Function to render a boolean value with icon
     * @param {Object} value The data value
     * @param {Object} metaData A collection of metadata about the current cell
     * @param {Ext.data.Model} record The record
     */
    renderBooleanIcon: function (value, metaData, record)
    {
        if (value != null)
        {
	        var isTrue = Ext.isBoolean(value) ? value : value == 'true';
	        if (isTrue)
	        {
                // if it's not a metadata cell render
                if (Ext.Object.isEmpty(metaData))
                {
                    return '<span class="a-grid-glyph ametysicon-check34" title="' + "{{i18n plugin.core-ui:PLUGINS_CORE_UI_GRID_COLUMN_BOOLEAN_YES}}" + '"></span>';
                }
	            return '<span class="a-grid-glyph a-grid-centered-glyph ametysicon-check34" title="' + "{{i18n plugin.core-ui:PLUGINS_CORE_UI_GRID_COLUMN_BOOLEAN_YES}}" + '"></span>';
	        }
	        else 
	        {
	            // if it's not a metadata cell render
	            if (Ext.Object.isEmpty(metaData))
                {
		            return '<span class="a-grid-glyph ametysicon-sign-raw-cross" title="' + "{{i18n plugin.core-ui:PLUGINS_CORE_UI_GRID_COLUMN_BOOLEAN_NO}}" + '"></span>';
                }
	            return '<span class="a-grid-glyph a-grid-centered-glyph ametysicon-sign-raw-small-cross" title="' + "{{i18n plugin.core-ui:PLUGINS_CORE_UI_GRID_COLUMN_BOOLEAN_NO}}" + '"></span>';
	        }
        }
        else // boolean value is not set
        {
            // if it's not a metadata cell render
            if (Ext.Object.isEmpty(metaData))
            {
                return '<span class="a-grid-glyph ametysicon-sign-question" title="' + "{{i18n plugin.core-ui:PLUGINS_CORE_UI_GRID_COLUMN_BOOLEAN_NOT_DEFINED}}" + '"></span>';
            }
            return "";
        }
    },
	
	/**
     * Function to render a TRUE boolean value with icon. If false or empty the cell will be empty.
     * @param {Object} value The data value
     * @param {Object} metaData A collection of metadata about the current cell
     * @param {Ext.data.Model} record The record
     */
    renderBooleanTrueIcon: function (value, metaData, record)
    {
		var isTrue = Ext.isBoolean(value) ? value : value == 'true';
        if (isTrue)
        {
            // if it's not a metadata cell render
            if (Ext.Object.isEmpty(metaData))
            {
                return '<span class="a-grid-glyph ametysicon-check34" title="' + "{{i18n plugin.core-ui:PLUGINS_CORE_UI_GRID_COLUMN_BOOLEAN_YES}}" + '"></span>';
            }
            return '<span class="a-grid-glyph a-grid-centered-glyph ametysicon-check34" title="' + "{{i18n plugin.core-ui:PLUGINS_CORE_UI_GRID_COLUMN_BOOLEAN_YES}}" + '"></span>';
        }
		return "";
    },
	
	/**
     * Convert a user object to a user light-object. The light version is the same handled by the user widget, so editing such user will not change the object
     * @param {Object/Object[]} value The value as a object with the value for each language
     * @param {Ext.data.Model} record The record
     * @param {String} dataIndex The model data index
     * @return {Object/Object[]} The property value or code.
     */
    convertUser: function (value, record, dataIndex)
    {
        let values = Ext.Array.from(value);
        
        if (values && values.length > 0)
        {
            let lightValues = [];
            for (let v of values)
            {
                let lightValue = {
                    fullname: v.fullname,
                    sortablename: v.sortablename,
                    login: v.login,
                    populationId: v.populationId,
                    populationLabel: v.populationLabel,
                };
                
                lightValues.push(lightValue);
            }
            
            return Ext.isArray(value) ? lightValues : lightValues[0];
        }
        return value;
    },
    
    /**
     * Function to render the user
     * Either by considering {@code value} as the diplay name of the user and
     * retrieving other user information from the record.
     * Or by relying only on {@code value} if its an object (or array of object)
     * @param {Object} value The data value.
     * @param {Object} metaData A collection of metadata about the current cell
     * @param {Ext.data.Model} record The record
     * @param {Number} rowIndex The index of the current row
     * @param {Number} colIndex The index of the current column
     * @param {Ext.data.Store} store The store
     * @param {Ext.view.View} view The current view
     * @param {String} dataIndex concatenated with '_user' will get the user additional informations. 
     */
    renderUser: function(value, metaData, record, rowIndex, colIndex, store, view, dataIndex)
    {
        let v = value;
        if (!Ext.isArray(v) && !Ext.isObject(v) && !Ext.isEmpty(record.get('login')))
        {
            v = {
                login: record.get('login'),
                populationId: record.get("populationId"),
                sortablename: v,
                populationLabel: record.get("populationLabel")
            }
        }
        
        if (Ext.isEmpty(v) || Ext.Object.isEmpty(v))
        {
            return '';
        }
        
        dataIndex = dataIndex || rowIndex; // When used by grouping feature, data index is the 4th arguments
        
        var values = Ext.Array.from(v);
        
        var html = '';
        for (var i=0; i < values.length; i++)
        {
            var userValue = values[i];
            var login = userValue.login;
            var populationId = userValue.populationId;
            
            if (!Ext.isEmpty(html))
            {
                html += '<br/>';
            }
            
            let knownUsername = userValue.sortablename || userValue.fullname;
            
            if (!knownUsername)
            {
                html += "<span class='a-grid-user-unknown'>"
            }
            html += `<img src="${Ametys.helper.Users.getUserImage(login, populationId, 16)}" class="a-grid-icon a-grid-icon-user"/>`;
            html += Ametys.helper.Users.renderUser(login, userValue.populationLabel || populationId, knownUsername);
            if (!knownUsername)
            {
                html += "</span>"
            }
        }
        
        return html;
    },
	
	/**
     * Function to render a date
     * @param {Object} value The data value
     * @param {Object} metaData A collection of metadata about the current cell
     * @param {Ext.data.Model} record The record
     * @param {Number} rowIndex The index of the current row
     * @param {Number} colIndex The index of the current column
     * @param {Ext.data.Store} store The store
     * @param {Ext.view.View} view The current view
     * @param {String} dataIndex concatenated with 'Display' will be the name of the dataIndex to display 
     */
    renderDate: function (value, metaData, record, rowIndex, colIndex, store, view, dataIndex)
    {
		if (!value)
		{
			return '-';
		}
		
        var date = Ext.isDate(value) ? value : Ext.Date.parse(value, Ext.Date.patterns.ISO8601DateTime);
        return Ext.Date.format(date, Ext.Date.patterns.LongDate);
    },

    /**
     * Function to render a datetime
     * @param {Object} value The data value
     * @param {Object} metaData A collection of metadata about the current cell
     * @param {Ext.data.Model} record The record
     * @param {Number} rowIndex The index of the current row
     * @param {Number} colIndex The index of the current column
     * @param {Ext.data.Store} store The store
     * @param {Ext.view.View} view The current view
     * @param {String} dataIndex concatenated with 'Display' will be the name of the dataIndex to display 
     */
    renderDateTime: function (value, metaData, record, rowIndex, colIndex, store, view, dataIndex)
    {
		if (!value)
		{
			return '-';
		}
				
        var date = Ext.isDate(value) ? value : Ext.Date.parse(value, Ext.Date.patterns.ISO8601DateTime);
        return Ext.Date.format(date, Ext.Date.patterns.FriendlyDateTime);
    }
});