using InABox.Core;
using InABox.Wpf;
using Microsoft.CodeAnalysis.Differencing;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;

namespace InABox.DynamicGrid;

public class FilterEditorControl : DynamicEditorControl<string, FilterEditor>
{
    private TextBox TextBox { get; set; }
    private Button Edit { get; set; }

    private IFilter? Filter { get; set; }

    private Type? _filterType { get; set; }

    public Type? FilterType
    {
        get => _filterType;
        set
        {
            if(_filterType != value)
            {
                if(TextBox != null)
                {
                    TextBox.Text = "";
                }
                Filter = null;
            }
            _filterType = value;
            if(Edit != null)
            {
                Edit.IsEnabled = value != null;
            }
            CheckChanged();
        }
    }

    public FilterEditorConfiguration Configuration { get; set; }

    public override int DesiredHeight()
    {
        return 25;
    }

    public override int DesiredWidth()
    {
        return int.MaxValue;
    }

    public override void SetColor(Color color)
    {
        TextBox.Background = new SolidColorBrush(color);
    }

    public override void SetFocus()
    {
        TextBox.Focus();
    }
    public override void Configure()
    {
    }

    protected override FrameworkElement CreateEditor()
    {
        FilterType = EditorDefinition.Type;

        var grid = new Grid
        {
            VerticalAlignment = VerticalAlignment.Stretch,
            HorizontalAlignment = HorizontalAlignment.Stretch
        };
        grid.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(1, GridUnitType.Star) });
        grid.ColumnDefinitions.Add(new ColumnDefinition { Width = GridLength.Auto });

        TextBox = new TextBox
        {
            VerticalAlignment = VerticalAlignment.Stretch,
            VerticalContentAlignment = VerticalAlignment.Center,
            HorizontalAlignment = HorizontalAlignment.Stretch,
            Margin = new Thickness(0, 0, 0, 0),
            IsEnabled = false
        };
        TextBox.SetValue(Grid.ColumnProperty, 0);
        TextBox.SetValue(Grid.RowProperty, 0);

        Edit = new Button
        {
            VerticalAlignment = VerticalAlignment.Stretch,
            VerticalContentAlignment = VerticalAlignment.Center,
            HorizontalAlignment = HorizontalAlignment.Stretch,
            Margin = new Thickness(5, 1, 0, 1),
            Width = 45,
            Content = "Edit",
            Focusable = false,
            IsEnabled = FilterType != null
        };
        Edit.SetValue(Grid.ColumnProperty, 1);
        Edit.SetValue(Grid.RowProperty, 0);
        Edit.Click += EditButton_Click;

        grid.Children.Add(TextBox);
        grid.Children.Add(Edit);

        return grid;
    }

    private void EditButton_Click(object sender, RoutedEventArgs e)
    {
        var window = new FilterEditorWindow(configuration: Configuration);
        var getMethod = typeof(FilterEditorWindow).GetMethod(nameof(FilterEditorWindow.GetFilter)).MakeGenericMethod(FilterType);
        var setMethod = typeof(FilterEditorWindow).GetMethod(nameof(FilterEditorWindow.SetFilter)).MakeGenericMethod(FilterType);

        IFilter? filter = Filter ?? Activator.CreateInstance(typeof(Filter<>).MakeGenericType(FilterType)) as IFilter;
        setMethod.Invoke(window, new object?[] { filter });

        if(window.ShowDialog() == true)
        {
            Filter = getMethod.Invoke(window, Array.Empty<object>()) as IFilter;
            TextBox.Text = Filter?.ToString();
            CheckChanged();
        }
    }

    protected override string RetrieveValue()
    {
        return Filter != null ? Serialization.Serialize(Filter) : "";
    }

    protected override void UpdateValue(string value)
    {
        if (FilterType != null)
            Filter = Serialization.Deserialize(typeof(Filter<>).MakeGenericType(FilterType), value) as IFilter;
        else
            Filter = null;
        TextBox.Text = Filter?.ToString();
    }
}
