using InABox.Wpf;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;

namespace InABox.DynamicGrid
{
    /// <summary>
    /// Interaction logic for ListWindow.xaml
    /// </summary>
    public partial class ArrayValueNodePopup : ThemableWindow
    {
        public ArrayValueNodePopup()
        {
            InitializeComponent();
        }

        public List<object?> GetList<TValueNode>() where TValueNode : ValueNode, new()
        {
            var grid = Content.Child as ListGrid<TValueNode>;
            if(grid == null)
            {
                return new();
            }
            return grid.GetList();
        }

        public void SetList<TValueNode>(IEnumerable<object?> values) where TValueNode : ValueNode, new()
        {
            var grid = new ListGrid<TValueNode>() { Margin = new Thickness(5) };
            grid.AddValues(values);
            Content.Child = grid;
        }

        private void Cancel_Click(object sender, RoutedEventArgs e)
        {
            DialogResult = false;
            Close();
        }

        private void OK_Click(object sender, RoutedEventArgs e)
        {
            DialogResult = true;
            Close();
        }
    }

    public class ListGrid<TValueNode> : Grid where TValueNode : ValueNode, new()
    {
        private bool bChanging;
        private List<Tuple<Button, TValueNode>> Nodes = new();
        private Button AddButton;

        public ListGrid()
        {
            ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(1, GridUnitType.Star) });
            ColumnDefinitions.Add(new ColumnDefinition { Width = GridLength.Auto });

            AddButton = new Button
            {
                Content = "+",
                Width = 20,
                Height = 20,
                VerticalAlignment = System.Windows.VerticalAlignment.Center,
                HorizontalAlignment = System.Windows.HorizontalAlignment.Center,
                VerticalContentAlignment = System.Windows.VerticalAlignment.Center,
                HorizontalContentAlignment = System.Windows.HorizontalAlignment.Center
            };
            AddButton.SetValue(ColumnProperty, 1);
            AddButton.Click += AddButton_Click;

            RefreshGrid();
        }
        private void RemoveNode(TValueNode node)
        {
            Nodes.RemoveAll(x => ReferenceEquals(x.Item2, node));
            RefreshGrid();
        }

        private void AddButton_Click(object sender, RoutedEventArgs e)
        {
            AddValue(null);
        }

        public void AddValue(object? value, int? index = null)
        {
            var node = new TValueNode()
            {
                Margin = new Thickness(0, 0, 5, 5)
            };
            if(value != null)
            {
                node.Value = value;
            }

            node.SetValue(ColumnProperty, 0);

            var removeButton = new Button
            {
                Content = "-",
                Margin = new Thickness(0, 0, 0, 5),

                Width = 20,
                Height = 20,

                VerticalAlignment = System.Windows.VerticalAlignment.Center,
                HorizontalAlignment = System.Windows.HorizontalAlignment.Center,
                VerticalContentAlignment = System.Windows.VerticalAlignment.Center,
                HorizontalContentAlignment = System.Windows.HorizontalAlignment.Center
            };
            removeButton.SetValue(ColumnProperty, 1);
            removeButton.Click += (s, e) =>
            {
                RemoveNode(node);
            };
            if(index is null || index.Value >= Nodes.Count)
            {
                Nodes.Add(new(removeButton, node));
            }
            else
            {
                Nodes.Insert(index.Value, new(removeButton, node));
            }

            if (!bChanging)
            {
                RefreshGrid();
            }
        }
        public void AddValues(IEnumerable<object?> values)
        {
            bChanging = true;
            foreach(var value in values)
            {
                AddValue(value);
            }
            bChanging = false;
            RefreshGrid();
        }

        public List<object?> GetList()
        {
            return Nodes.Select(x => x.Item2.Value).ToList();
        }

        private void RefreshGrid()
        {
            RowDefinitions.Clear();
            Children.Clear();

            var row = 0;
            foreach (var (btn, node) in Nodes)
            {
                RowDefinitions.Add(new RowDefinition { Height = GridLength.Auto });

                btn.SetValue(RowProperty, row);
                node.SetValue(RowProperty, row);

                Children.Add(btn);
                Children.Add(node);

                row++;
            }

            RowDefinitions.Add(new RowDefinition { Height = GridLength.Auto });
            AddButton.SetValue(RowProperty, row);
            Children.Add(AddButton);
        }
    }
}
