using System.Reflection;
using System.Windows.Input;

namespace GreadyPoang.Common;
public class EventToCommandBehavior : BehaviorBase<VisualElement>
{
    public string EventName { get; set; }

    public static readonly BindableProperty CommandProperty =
        BindableProperty.Create(nameof(Command), typeof(ICommand), typeof(EventToCommandBehavior));

    public ICommand Command
    {
        get => (ICommand)GetValue(CommandProperty);
        set => SetValue(CommandProperty, value);
    }

    private EventInfo eventInfo;
    private Delegate eventHandler;

    protected override void OnAttachedTo(VisualElement bindable)
    {
        base.OnAttachedTo(bindable);

        if (bindable == null || string.IsNullOrEmpty(EventName))
            return;

        eventInfo = bindable.GetType().GetRuntimeEvent(EventName);
        if (eventInfo == null)
            throw new ArgumentException($"Event '{EventName}' not found on type '{bindable.GetType().Name}'");

        MethodInfo methodInfo = typeof(EventToCommandBehavior).GetTypeInfo().GetDeclaredMethod(nameof(OnEvent));
        eventHandler = methodInfo.CreateDelegate(eventInfo.EventHandlerType, this);
        eventInfo.AddEventHandler(bindable, eventHandler);
    }

    protected override void OnDetachingFrom(VisualElement bindable)
    {
        base.OnDetachingFrom(bindable);

        if (eventInfo != null && eventHandler != null)
            eventInfo.RemoveEventHandler(bindable, eventHandler);
    }

    private void OnEvent(object sender, object eventArgs)
    {
        if (Command?.CanExecute(eventArgs) == true)
            Command.Execute(eventArgs);
    }
}
