using System.ComponentModel;
using System.Globalization;

namespace VisionBuilder.UI.Common.Utils;

public abstract class GeneralListTypeConverter<T>:TypeConverter
    where T: class
{
    public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
    {
        return sourceType == typeof(string) || base.CanConvertFrom(context, sourceType);
    }

    public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType)
    {
        return destinationType == typeof(string) || base.CanConvertTo(context, destinationType);
    }

    public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
    {
        if (value is string stringValue)
        {
            // Check if we're converting to a single ErrorShortName
            if (context?.PropertyDescriptor?.PropertyType == typeof(T))
            {
                return ConvertFromString(context, culture, stringValue);
            }

            // Otherwise, convert to a list of ErrorShortName
            var errorShortNames = new List<T>();
            if (!string.IsNullOrEmpty(stringValue))
            {
                var lines = stringValue.Split('\n', StringSplitOptions.RemoveEmptyEntries);

                foreach (var line in lines)
                {
                    var errorShortName = ConvertFromString(context, culture, line.Trim());
                    if (errorShortName != null)
                        errorShortNames.Add(errorShortName);
                }
            }

            return errorShortNames;
        }

        return base.ConvertFrom(context, culture, value);
    }

    public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value,
        Type destinationType)
    {
        if (destinationType == typeof(string))
        {
            // Handle single ErrorShortName
            if (value is T errorShortName)
            {
                return this.ConvertToString(context, culture, errorShortName);
            }

            // Handle list of ErrorShortName
            if (value is List<T> errorShortNames)
            {
                var lines = errorShortNames.Select(e =>
                    ConvertToString(context, culture, e)
                ).Where(line => !string.IsNullOrEmpty(line));

                return string.Join("\n", lines);
            }
        }

        return base.ConvertTo(context, culture, value, destinationType);
    }

    /// <summary>
    /// Convert a single string to ErrorShortName
    /// </summary>
    protected abstract T ConvertFromString(ITypeDescriptorContext context, CultureInfo culture,
        string stringValue);

    /// <summary>
    /// Convert a single ErrorShortName to string
    /// </summary>
    protected abstract string ConvertToString(ITypeDescriptorContext context, CultureInfo culture,
        T errorShortName);
}