using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using InABox.Core;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Xceed.Wpf.Toolkit.Primitives;

namespace InABox.DynamicGrid;

public class OperatorNode : StackPanel
{
    public delegate void OperatorChangedHandler(Operator op, bool isNot);

    public event OperatorChangedHandler? OperatorChanged;

    public Operator SelectedOperator => (Operator)_boxes.Last().SelectedItem;

    public bool IsNot => _boxes.Count % 2 == 0;

    private List<ComboBox> _boxes = new List<ComboBox>();

    public OperatorNode(Operator op, bool isNot)
    {
        Orientation = Orientation.Horizontal;
        VerticalAlignment = System.Windows.VerticalAlignment.Stretch;

        if (isNot)
        {
            AddBox(Operator.Not);
            AddBox(op);
        }
        else
        {
            AddBox(op);
        }
    }

    private ComboBox AddBox(Operator selectedItem)
    {
        var box = new ComboBox();

        box.VerticalAlignment = System.Windows.VerticalAlignment.Stretch;
        box.VerticalContentAlignment = System.Windows.VerticalAlignment.Center;

        foreach (var value in Enum.GetValues<Operator>())
        {
            box.Items.Add(value);
        }
        box.SelectedItem = selectedItem;
        box.SelectionChanged += ComboBox_SelectionChanged;

        if(_boxes.Count > 0)
        {
            box.Margin = new Thickness(5, 0, 0, 0);
        }

        _boxes.Add(box);
        Children.Add(box);

        return box;
    }

    public void Clear()
    {
        _boxes.Clear();
        Children.Clear();

        AddBox(default);
        OperatorChanged?.Invoke(default, false);
    }

    private void ComboBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
    {
        if (sender is not ComboBox box) return;

        var selected = (Operator?)box.SelectedItem ?? Operator.IsEqualTo;

        if (box == _boxes.Last())
        {
            if(selected == Operator.Not)
            {
                AddBox(default);
                OperatorChanged?.Invoke(SelectedOperator, IsNot);
            }
        }
        else
        {
            if(selected != Operator.Not)
            {
                var idx = _boxes.IndexOf(box);
                Children.RemoveRange(idx + 1, _boxes.Count - idx);
                _boxes.RemoveRange(idx + 1, _boxes.Count - (idx + 1));
                OperatorChanged?.Invoke(SelectedOperator, IsNot);
            }
        }
        OperatorChanged?.Invoke(SelectedOperator, IsNot);
    }
}