using System.ComponentModel;
using System.Globalization;

namespace VisionBuilder.UI.IOCommander;

public class IOCommanderProcessingEvent
{
    public IOCommanderProcessingEvent(EProcessingEvent @event)
    {
        Event = @event;
    }

    public EProcessingEvent Event { get; set; }
    public List<IOCommanderPinAction> Actions { get; set; } = new List<IOCommanderPinAction>();
}

public class IOCommanderPinActionListConverter : TypeConverter
{
    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 IOCommanderPinAction
            if (context?.PropertyDescriptor?.PropertyType == typeof(IOCommanderPinAction))
            {
                return ConvertFromString(context, culture, stringValue);
            }
            
            // Otherwise, convert to a list of IOCommanderPinAction
            var actions = new List<IOCommanderPinAction>();
            if (!string.IsNullOrEmpty(stringValue))
            {
                var lines = stringValue.Split('\n', StringSplitOptions.RemoveEmptyEntries);

                foreach (var line in lines)
                {
                    var action = ConvertFromString(context, culture, line.Trim());
                    if (action != null)
                        actions.Add(action);
                }
            }
            return actions;
        }
        return base.ConvertFrom(context, culture, value);
    }

    public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType)
    {
        if (destinationType == typeof(string))
        {
            // Handle single IOCommanderPinAction
            if (value is IOCommanderPinAction action)
            {
                return ConvertToString(context, culture, action);
            }
            
            // Handle list of IOCommanderPinAction
            if (value is List<IOCommanderPinAction> actions)
            {
                var lines = actions.Select(a =>
                    ConvertToString(context, culture, a)
                ).Where(line => !string.IsNullOrEmpty(line));

                return string.Join("\n", lines);
            }
        }
        return base.ConvertTo(context, culture, value, destinationType);
    }

    /// <summary>
    /// Convert a single string to IOCommanderPinAction
    /// </summary>
    private IOCommanderPinAction ConvertFromString(ITypeDescriptorContext context, CultureInfo culture, string stringValue)
    {
        if (string.IsNullOrEmpty(stringValue))
            return null;

        var parts = stringValue.Split(',');
        if (parts.Length == 3)
        {
            if (int.TryParse(parts[0], out int pin) &&
                bool.TryParse(parts[1], out bool inverted) &&
                bool.TryParse(parts[2], out bool pulse))
            {
                return new IOCommanderPinAction
                {
                    Pin = pin,
                    Low = inverted,
                    Pulse = pulse
                };
            }
        }
        return null;
    }

    /// <summary>
    /// Convert a single IOCommanderPinAction to string
    /// </summary>
    private string ConvertToString(ITypeDescriptorContext context, CultureInfo culture, IOCommanderPinAction action)
    {
        if (action == null)
            return null;

        return $"{action.Pin},{action.Low},{action.Pulse}";
    }
}