using Avalonia.Controls;
using Avalonia.Media;
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using InABox.Core;

namespace InABox.Avalonia.Components;

public partial class AvaloniaMenuItem : ObservableObject
{
    [ObservableProperty] 
    private RelayCommand<List<AvaloniaMenuItem>>? _buildMenuCommand;

    [ObservableProperty] 
    private ContextMenu? _contextMenu;

    [ObservableProperty] 
    private IImage? _image;

    [ObservableProperty] 
    private RelayCommand? _tapCommand;

    [ObservableProperty] 
    private bool _isVisible = true;

    public AvaloniaMenuItem()
    {
    }

    public AvaloniaMenuItem(IImage? image, Func<Task<bool>> action)
        : this(image, () => null, action)
    {
    }

    public AvaloniaMenuItem(IImage? image, Action action)
        : this(image, () => null, () =>
        {
            action();
            return Task.FromResult(true);
        })
    {
    }

    public AvaloniaMenuItem(IImage? image, Func<CoreMenu<IImage>?> build, Func<Task<bool>>? action = null)
    {
        Image = image; //LoadImage(image);

        TapCommand = new RelayCommand(() =>
        {
            CoreMenu<IImage>? menu = build();
            if (menu != null)
            {
                var context = new ContextMenu();
                LoadMenuItems(menu.Items, context.Items);
                ContextMenu = context;
                ContextMenu.Open();
            }
            else if (action != null)
            {
                _ = action();
            }
        });

        //_contextMenu = new();
        //LoadMenuItems(build().Items,_contextMenu.Items);
    }
    
    public static void LoadMenuItems(IEnumerable<ICoreMenuItem> sourceItems, ItemCollection targetItems)
    {
        foreach (var sourceItem in sourceItems)
            if (sourceItem is CoreMenuSeparator)
            {
                targetItems.Add(new Separator());
            }

            else if (sourceItem is CoreMenuItem<IImage> item)
            {
                if(item.IsVisible is null || item.IsVisible())
                {
                    var targetItem = new MenuItem
                    {
                        Header = item.Header,
                        Icon = new Image { Source = item.Image },
                        Command = item.Action != null
                            ? new RelayCommand(() => item.Action())
                            : null
                    };
                    targetItems.Add(targetItem);
                }
            }
            else if (sourceItem is CoreMenuHeader<IImage> header)
            {
                var targetItem = new MenuItem
                {
                    Header = header.Header,
                    Icon = header.Image
                };
                LoadMenuItems(header.Items, targetItem.Items);
                targetItems.Add(targetItem);
            }
    }
}