using DynamicData;
using DynamicData.Binding;
using Ryujinx.Ava.UI.Models;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;

namespace Ryujinx.Ava.UI.ViewModels;

public class UserSaveManagerViewModel : BaseModel
{
    private int _sortIndex;
    private int _orderIndex;
    private string _search;
    private ObservableCollection<SaveModel> _saves;
    private ObservableCollection<SaveModel> _views;

    public int SortIndex
    {
        get => _sortIndex;
        set
        {
            _sortIndex = value;
            OnPropertyChanged();
            Sort();
        }
    }

    public int OrderIndex
    {
        get => _orderIndex;
        set
        {
            _orderIndex = value;
            OnPropertyChanged();
            Sort();
        }
    }

    public string Search
    {
        get => _search;
        set
        {
            _search = value;
            OnPropertyChanged();
            Sort();
        }
    }

    public ObservableCollection<SaveModel> Saves
    {
        get => _saves;
        set
        {
            _saves = value;
            OnPropertyChanged();
            Sort();
        }
    }
    
    public ObservableCollection<SaveModel> Views
    {
        get => _views;
    }

    public UserSaveManagerViewModel()
    {
        _saves = new ObservableCollection<SaveModel>();
        _views = new ObservableCollection<SaveModel>();
    }
    
    public void Sort()
    {
        Saves.AsObservableChangeSet()
            .Filter(Filter)
            .Sort(GetComparer())
            .Bind(out var view).AsObservableList();
            
        _views.Clear();
        _views.AddRange(view);
        OnPropertyChanged(nameof(Views));
    }
    
    private bool Filter(object arg)
    {
        if (arg is SaveModel save)
        {
            return string.IsNullOrWhiteSpace(_search) || save.Title.ToLower().Contains(_search.ToLower());
        }

        return false;
    }
    
    private IComparer<SaveModel> GetComparer()
    {
        switch (SortIndex)
        {
            case 0:
                return OrderIndex == 0
                    ? SortExpressionComparer<SaveModel>.Ascending(save => save.Title)
                    : SortExpressionComparer<SaveModel>.Descending(save => save.Title);
            case 1:
                return OrderIndex == 0
                    ? SortExpressionComparer<SaveModel>.Ascending(save => save.Size)
                    : SortExpressionComparer<SaveModel>.Descending(save => save.Size);
            default:
                return null;
        }
    }
}