using System;
using System.Collections.Generic;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Media;
using InABox.Clients;
using InABox.Core;
using InABox.WPF;
using java.util;

namespace InABox.DynamicGrid
{
    public class TextBoxDecorator : Decorator
    {
        // properties
        public override UIElement Child
        {
            get => base.Child;
            set
            {
                var oldValue = base.Child;

                if (oldValue != null)
                {
                    //var wbind = BindingOperations.GetBinding(oldValue, FrameworkElement.WidthProperty);
                    //if ((wbind != null) && (wbind.Source == this))
                    //    BindingOperations.ClearBinding(oldValue, FrameworkElement.WidthProperty);

                    var hbind = BindingOperations.GetBinding(oldValue, HeightProperty);
                    if (hbind != null && hbind.Source == this)
                        BindingOperations.ClearBinding(oldValue, HeightProperty);
                }

                base.Child = value;

                if (value != null &&
                    BindingOperations.GetBinding(value, HeightProperty) == null)
                    BindingOperations.SetBinding(
                        value,
                        HeightProperty,
                        new Binding
                        {
                            Source = this,
                            Path = new PropertyPath(ActualHeightProperty),
                            Mode = BindingMode.OneWay
                        });
            }
        }

        // methods
        protected override Size MeasureOverride(Size constraint)
        {
            var result = base.MeasureOverride(constraint);

            if (double.IsInfinity(constraint.Height))
                result.Height = (Child as FrameworkElement)?.MinHeight ?? 0.0;

            return result;
        }
    }

    public class NotesEditorControl : DynamicEditorControl<string[], NotesEditor>
    {
        static NotesEditorControl()
        {
            //DynamicEditorControlFactory.Register<NotesEditorControl, NotesEditor>();
        }
        
        private Color BGColor = Colors.Gainsboro;

        //private TextBox Editor = null;
        private Button Button;
        private Grid Grid;
        private TextBox History;
        private TextBoxDecorator Scroll;

        private string[]? _value = [];

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

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

        public override void SetColor(Color color)
        {
            BGColor = color;
            if (!History.IsReadOnly)
                History.Background = new SolidColorBrush(color);
        }

        public override void SetFocus()
        {
            Button.Focus();
        }

        public override void Configure()
        {
        }

        protected override FrameworkElement CreateEditor()
        {
            VerticalAlignment = VerticalAlignment.Stretch;
            MinHeight = 250;
            Grid = new Grid();
            Grid.VerticalAlignment = VerticalAlignment.Stretch;
            Grid.RowDefinitions.Add(new RowDefinition { Height = new GridLength(1, GridUnitType.Star) });
            Grid.RowDefinitions.Add(new RowDefinition { Height = new GridLength(1, GridUnitType.Auto) });
            Grid.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(1, GridUnitType.Star) });
            Grid.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(1, GridUnitType.Auto) });

            Scroll = new TextBoxDecorator
            {
                VerticalAlignment = VerticalAlignment.Stretch,
                HorizontalAlignment = HorizontalAlignment.Stretch
                //HorizontalContentAlignment = HorizontalAlignment.Stretch,
                //VerticalScrollBarVisibility = ScrollBarVisibility.Visible,
                //HorizontalScrollBarVisibility = ScrollBarVisibility.Disabled,
                //Background = new SolidColorBrush(Colors.Yellow)
            };
            Scroll.SetValue(Grid.RowProperty, 0);
            Scroll.SetValue(Grid.RowSpanProperty, 2);
            Scroll.SetValue(Grid.ColumnProperty, 0);
            Scroll.SetValue(Grid.ColumnSpanProperty, 2);

            Grid.Children.Add(Scroll);

            History = new TextBox
            {
                VerticalAlignment = VerticalAlignment.Top,
                VerticalContentAlignment = VerticalAlignment.Stretch,
                HorizontalAlignment = HorizontalAlignment.Stretch,
                TextWrapping = TextWrapping.Wrap,
                AcceptsReturn = true,
                IsReadOnly = true,
                VerticalScrollBarVisibility = ScrollBarVisibility.Auto
            };

            History.IsVisibleChanged += (o, e) =>
            {
                History.Focus();
                History.CaretIndex = History.Text.Length;
                History.ScrollToEnd();
            };

            History.TextChanged += (o, e) =>
            {
                if (History.IsReadOnly)
                {
                    History.Focus();
                    History.CaretIndex = History.Text.Length;
                    History.ScrollToEnd();
                }
                else
                {
                    CheckChanged();
                }
            };

            Scroll.Child = History;
            
            Button = new Button
            {
                VerticalAlignment = VerticalAlignment.Stretch,
                VerticalContentAlignment = VerticalAlignment.Center,
                HorizontalAlignment = HorizontalAlignment.Stretch,
                HorizontalContentAlignment = HorizontalAlignment.Center,
                BorderThickness = new Thickness(0F),
                Background = Brushes.Transparent,
                Content = new Image() { Source = Wpf.Resources.add.AsBitmapImage() },
                Width = 48,
                Height=48,
                Margin=new Thickness(0,0,5,5)
            };
            Button.Click += Button_Click;
            Button.SetValue(Grid.RowProperty, 1);
            Button.SetValue(Grid.ColumnProperty, 1);
            Grid.Children.Add(Button);

            return Grid;
        }

        private void Button_Click(object sender, RoutedEventArgs e)
        {
            var popup = new NotePopup { Caption = "Add Note", Text = "" };
            if (popup.ShowDialog() == true)
            {
                if (string.IsNullOrEmpty(History.Text))
                {
                    _value = [popup.Text];
                }
                else
                {
                    _value = (_value ?? []).Concatenate([string.Format("{0:yyyy-MM-dd HH:mm:ss} {1}: {2}", DateTime.Now, ClientFactory.UserID, popup.Text)]);
                }
                History.Text = NotesEditor.FormatNotes(_value);

                History.ScrollToEnd();
                CheckChanged();
            }
        }

        protected override string[] RetrieveValue()
        {
            if(_value is null || _value.Length == 0 && !History.Text.IsNullOrWhiteSpace())
            {
                return [$"{DateTime.Now:yyyy-MM-dd HH:mm:ss} {ClientFactory.UserID}: {History.Text}"];
            }
            return _value;
        }

        protected override void UpdateValue(string[] value)
        {
            if(value is not null)
            {
                _value = value;
                History.Text = NotesEditor.FormatNotes(_value);
            }
            else
            {
                _value = null;
                History.Text = "";
            }

            var AlwaysEnabled = EditorDefinition is NotesEditor && ((NotesEditor)EditorDefinition).AlwaysEnabled;
            History.IsReadOnly = !AlwaysEnabled && !string.IsNullOrWhiteSpace(History.Text);
            History.Background = History.IsReadOnly ? new SolidColorBrush(Colors.Gainsboro) : new SolidColorBrush(BGColor);
            Button.Visibility = History.IsReadOnly ? Visibility.Visible : Visibility.Collapsed;
            History.Focus();
            History.CaretIndex = History.Text.Length;
            History.ScrollToEnd();
        }
    }
}