using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Windows.Media.Imaging;
using InABox.Core;
using InABox.WPF;

namespace InABox.DynamicGrid;

public class DynamicExportMappingGrid : DynamicGrid<ImportMapping>
{
    private readonly BitmapImage selected = Wpf.Resources.Bullet_Tick.AsBitmapImage();

    public DynamicExportMappingGrid()
    {
        HideBlank = false;

        Items = new List<ImportMapping>();
        Selected = new List<ImportMapping>();

        ActionColumns.Add(new DynamicImageColumn(SelectedImage, SelectedAction));
        HiddenColumns.Add(x => x.Key);
    }

    public List<ImportMapping> Items { get; }

    public List<ImportMapping> Selected { get; }

    public bool HideBlank { get; set; }

    public override void DeleteItems(params CoreRow[] rows)
    {
        var deletes = new List<ImportMapping>();
        foreach (var row in rows)
            deletes.Add(Items[row.Index]);
        Items.RemoveAll(x => deletes.Contains(x));
        Selected.RemoveAll(x => deletes.Contains(x));
    }

    public override ImportMapping LoadItem(CoreRow row)
    {
        return Items[row.Index];
    }

    protected override void Reload(
        Filters<ImportMapping> criteria, Columns<ImportMapping> columns, ref SortOrder<ImportMapping>? sort, 
        CancellationToken token, Action<CoreTable?, Exception?> action)
    {
        var result = new CoreTable();
        result.LoadColumns(typeof(ImportMapping));
        if (HideBlank)
            result.LoadRows(Items.Where(x => Selected.Contains(x)));
        else
            result.LoadRows(Items);
        action.Invoke(result, null);
    }

    public override void SaveItem(ImportMapping item)
    {
        if (!Items.Contains(item))
            Items.Add(item);
    }

    protected override DynamicGridColumns LoadColumns()
    {
        return new DynamicGridColumns()
            .AddFluent<ImportMapping>(x => x.Property, width: 0);
    }

    public void ClearAll()
    {
        Selected.Clear();
        Selected.AddRange(Items.Where(x => x.Key));
        Refresh(false, true);
    }

    public void SelectAll()
    {
        Selected.Clear();
        Selected.AddRange(Items);
        Refresh(false, true);
    }

    private BitmapImage SelectedImage(CoreRow? arg)
    {
        if (arg == null)
            return selected;
        var property = arg.Get<ImportMapping, string>(x => x.Property);
        return Selected.Any(x => x.Property.Equals(property)) ? selected : null;
    }

    private bool SelectedAction(CoreRow? arg)
    {
        var property = arg?.Get<ImportMapping, string>(x => x.Property);
        var items = arg == null ? Items.ToArray() : new[] {  Items.Where(x => x.Property.Equals(property)).First() };
        foreach (var item in items)
            if (Selected.Contains(item) && !item.Key)
                Selected.Remove(item);
            else
                Selected.Add(item);
        return true;
    }
}