using InABox.Core;
using Syncfusion.Data;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;

namespace InABox.DynamicGrid;

public interface IDynamicGridUIComponentParent<T> : IDynamicGrid<T>
    where T : BaseObject, new()
{
    bool IsRefreshing { get; }

    bool CanSort();

    DynamicGridRowStyleSelector<T> RowStyleSelector { get; }

    void BeforeSelection(CancelEventArgs cancel);

    void SelectItems(CoreRow[] rows);

    void HandleKey(KeyEventArgs args);

    void LoadColumnsMenu(ContextMenu menu);

    void DoubleClickCell(CoreRow? row, DynamicColumnBase? column);
    void ExecuteActionColumn(DynamicActionColumn column, CoreRow[]? rows);
    void OpenColumnMenu(DynamicColumnBase column);

    void UpdateData(T obj, CoreRow row, string changedColumn, Dictionary<CoreColumn, object?> updates);
    void EntityChanged(T obj, CoreRow row, string changedColumn, Dictionary<string, object?> changes);

    void UpdateRecordCount(int count);
    public bool IsDirectEditMode();

    void DragOver(object sender, DragEventArgs e);
    void Drop(object sender, DragEventArgs e);
    void DragStart(object? sender, CoreRow[] rows);

    void UIFilterChanged(object sender);
    IEnumerable<string>? GetColumnFilterItems(DynamicColumnBase column);
}

public interface IDynamicGridUIComponent<T>
    where T : BaseObject, new()
{
    IDynamicGridUIComponentParent<T> Parent { get; set; }

    FrameworkElement Control { get; }
    
    CoreRow[] SelectedRows { get; set; }

    double RowHeight { get; set; }
    double HeaderRowHeight { get; set; }
    int DesiredWidth();

    /// <summary>
    /// Do any required updates when the options list is changed.
    /// </summary>
    /// <returns>Whether the columns need to be reloaded.</returns>
    bool OptionsChanged();

    void UpdateRow(CoreRow row);
    void UpdateCell(CoreRow row, string column, object? value);

    void AddVisualFilter(string column, string value, FilterType filtertype = FilterType.Contains);
    List<Tuple<string, Func<CoreRow, bool>>> GetFilterPredicates();

    void BeforeRefresh();
    void RefreshColumns(DynamicGridColumns columns, DynamicActionColumns actionColumns, DynamicGridColumnGroupings groupings);
    void RefreshData(CoreTable data);
    void AddPage(IEnumerable<CoreRow> page);
    void InvalidateRow(CoreRow row);

    void ScrollIntoView(CoreRow row);
    CoreRow[] GetVisibleRows();
}
