using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using InABox.Core;

namespace InABox.DynamicGrid;

public class FilterComponent : Grid
{
    private TextBox Display;
    private Button Edit;
    private BaseFilterNode? FilterNode;

    private Type? _filterType;
    public Type? FilterType
    {
        get => _filterType;
        set
        {
            _filterType = value;
            HideFilter(value == null);
            Filter = null;
        }
    }

    private IFilter? _filter;
    private IFilter? Filter
    {
        get => _filter;
        set
        {
            _filter = value;
            Display.Text = _filter?.AsOData() ?? "";
        }
    }
    private bool Hidden = true;

    public FilterComponent(IFilter? filter)
    {
        ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(1, GridUnitType.Star) });
        ColumnDefinitions.Add(new ColumnDefinition { Width = GridLength.Auto });

        RowDefinitions.Add(new RowDefinition { Height = GridLength.Auto });
        RowDefinitions.Add(new RowDefinition { Height = new GridLength(1, GridUnitType.Star) });

        Display = new TextBox
        {
            VerticalAlignment = System.Windows.VerticalAlignment.Stretch,
            VerticalContentAlignment = System.Windows.VerticalAlignment.Center,
            Background = new SolidColorBrush(Colors.LightYellow),
            IsEnabled = false,
            Margin = new Thickness(0, 0, 5, 5)
        };
        Display.SetValue(Grid.RowProperty, 0);
        Display.SetValue(Grid.ColumnProperty, 0);

        Edit = new Button
        {
            Content = "Edit",
            IsEnabled = false,
            Margin = new Thickness(0, 0, 0, 5),
            Padding = new Thickness(5)
        };
        Edit.SetValue(Grid.RowProperty, 0);
        Edit.SetValue(Grid.ColumnProperty, 1);
        Edit.Click += Edit_Click;

        Children.Add(Display);
        Children.Add(Edit);

        Filter = filter;

        HideFilter();
    }

    private void Edit_Click(object sender, RoutedEventArgs e)
    {
        if (Hidden)
        {
            EditFilter();
        }
        else
        {
            HideFilter();
        }
    }

    private void HideFilter(bool disable = false)
    {
        Hidden = true;
        Edit.Content = "Edit";
        Edit.IsEnabled = !disable;

        if (FilterNode != null)
        {
            Filter = FilterNode.GetFilter();

            Children.Remove(FilterNode);
            FilterNode = null;
        }
    }

    public void EditFilter()
    {
        if (FilterType == null)
            return;

        Hidden = false;
        Edit.Content = "Hide";

        var filter = Filter ?? Activator.CreateInstance(typeof(Filter<>).MakeGenericType(FilterType)) as IFilter;

        Filter = filter;
        if (FilterNode != null)
            Children.Remove(FilterNode);

        FilterNode = (Activator.CreateInstance(typeof(FilterNode<>).MakeGenericType(FilterType), filter, FilterNodeType.ROOT) as BaseFilterNode)!;
        FilterNode.SetValue(Grid.RowProperty, 1);
        FilterNode.SetValue(Grid.ColumnProperty, 0);
        FilterNode.SetValue(Grid.ColumnSpanProperty, 2);

        Children.Add(FilterNode);
    }

    public IFilter? GetFilter() => Hidden ? Filter : FilterNode?.GetFilter();

    public void SetFilter(IFilter? filter)
    {
        Filter = filter;
        if (filter == null)
        {
            HideFilter();
        }
        else
        {
            if (!Hidden)
                EditFilter();
        }
    }
}