using System;
using System.Collections.ObjectModel;
using System.ComponentModel;
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));

    [ObservableProperty] private AvaloniaModule[] _visibleItems = [];

    public AvaloniaModuleCollection()
    {
        Items.CollectionChanged += (sender, args) => UpdateVisibleItems();
    }
    
    public void Add()
    {
        var module = new AvaloniaModule();
        module.PropertyChanged += DoPropertyChanged;
        Items.Add(module);
    }

    private void DoPropertyChanged(object? sender, PropertyChangedEventArgs e)
    {
        if (e.PropertyName == nameof(AvaloniaModule.IsVisible))
            UpdateVisibleItems();
    }

    private void UpdateVisibleItems()
    {
        VisibleItems = Items.Where(x=>x.IsVisible == true).ToArray();
    }

    public AvaloniaModule Add(string title, string description, SvgImage? image, Action action, bool? isVisible = null
        /* Func<PrsModule, Task>? configure = null */)
    {
        var module = new AvaloniaModule
        {
            Title = title,
            Description = description,
            Image = image,
            TapCommand = new RelayCommand(action),
            IsVisible = isVisible ?? true
        };
        module.PropertyChanged += DoPropertyChanged;
        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, bool? isVisible = null)
        where TViewModel : IViewModelBase
    {
        var module = new AvaloniaModule
        {
            Title = title,
            Description = description,
            Image = image,
            TapCommand = new RelayCommand(() => Navigation.Navigate<TViewModel>(configure)),
            IsVisible = isVisible ?? true
        };
        module.PropertyChanged += DoPropertyChanged;
        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, bool? isVisible = null)
        where TToken : ISecurityDescriptor, new()
        where TViewModel : IViewModelBase
    {
        if (Security.IsAllowed<TToken>())
            return Add<TViewModel>(title, description, image, configure, isVisible);
        return null;
    }
}