using System.Collections;
using System.Globalization;

namespace ZB.MOM.WW.ScadaBridge.Commons.Types;

/// <summary>
/// Formats attribute values for display. Handles scalar types directly
/// and converts arrays/collections to comma-separated strings.
/// </summary>
public static class ValueFormatter
{
    /// <summary>
    /// Formats a value as a string. Returns the value's string representation for
    /// scalars and comma-separated elements for array/collection types.
    /// </summary>
    /// <param name="value">The value to format; null returns an empty string.</param>
    /// <returns>The culture-invariant string representation of the value, or an empty string if <paramref name="value"/> is <c>null</c>.</returns>
    /// <remarks>
    /// Formatting is <see cref="CultureInfo.InvariantCulture">culture-invariant</see>:
    /// numbers and <see cref="DateTime"/> values render the same regardless of the
    /// server/thread locale. This is required because the formatter feeds non-UI
    /// contexts (gRPC stream events, logs, diff display) where locale-dependent
    /// output (decimal separators, date order) would be inconsistent.
    /// </remarks>
    public static string FormatDisplayValue(object? value)
    {
        if (value is null) return "";
        if (value is string s) return s;
        if (value is IFormattable formattable)
            return formattable.ToString(null, CultureInfo.InvariantCulture) ?? "";

        if (value is IEnumerable enumerable)
        {
            return string.Join(",", enumerable.Cast<object?>().Select(FormatElement));
        }

        return value.ToString() ?? "";
    }

    private static string FormatElement(object? element) => element switch
    {
        null => "",
        string str => str,
        IFormattable f => f.ToString(null, CultureInfo.InvariantCulture) ?? "",
        _ => element.ToString() ?? ""
    };
}
