using System;
using System.Collections.ObjectModel;
using System.Linq;
using System.Threading.Tasks;
using Avalonia.Svg.Skia;
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using InABox.Core;

namespace InABox.Avalonia.Components;

public partial class AvaloniaModuleCollection : ObservableObject
{
    [ObservableProperty] private ObservableCollection<AvaloniaModule> _items = new();

    public AvaloniaModule? this[string name] => Items.FirstOrDefault(x => Equals(x.Title, name));

    public void Add()
    {
        var module = new AvaloniaModule();
        Items.Add(module);
    }

    public AvaloniaModule Add(string title, string description, SvgImage? image, Action action
        /* Func<PrsModule, Task>? configure = null */)
    {
        var module = new AvaloniaModule
        {
            Title = title,
            Description = description,
            Image = image,
            TapCommand = new RelayCommand(action)
        };
        Items.Add(module);
        // _ = configure?.Invoke(module);
        return module;
    }

    public AvaloniaModule Add<TViewModel>(string title, string description, SvgImage? image,
        /* Func<PrsModule, Task>? configure = null */ Action<TViewModel>? configure = null)
        where TViewModel : IViewModelBase
    {
        var module = new AvaloniaModule
        {
            Title = title,
            Description = description,
            Image = image,
            TapCommand = new RelayCommand(() => Navigation.Navigate<TViewModel>(configure))
        };
        Items.Add(module);
        // _ = configure?.Invoke(module);
        return module;
    }

    public AvaloniaModule? Add<TToken, TViewModel>(string title, string description, SvgImage? image,
        /* Func<PrsModule, Task>? configure = null */ Action<TViewModel>? configure = null)
        where TToken : ISecurityDescriptor, new()
        where TViewModel : IViewModelBase
    {
        if (Security.IsAllowed<TToken>())
            return Add<TViewModel>(title, description, image, configure);
        return null;
    }
}