using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Markup;
using System.Windows.Media;
using InABox.Core;
using InABox.WPF;
using RoslynPad.Editor;
using Syncfusion.Windows.Shared;
using Syncfusion.Windows.Tools.Controls;
using ItemsPanelTemplate = System.Windows.Controls.ItemsPanelTemplate;

namespace InABox.DynamicGrid
{
    public class CheckListEditorControl : DynamicEditorControl<Dictionary<string, bool>, CheckListEditor>, ILookupEditorControl
    {
        
        static CheckListEditorControl()
        {
            //DynamicEditorControlFactory.Register<CheckListEditorControl, CheckListEditor>();
            
        }
        
        private SolidColorBrush _color;

        private Dictionary<object, string> _lookups;

        private Type _realtype;
        private Dictionary<string, bool> _value;
        private bool bLoading;

        private CheckListBox Editor;

        public ILookupEditor LookupEditorDefinition => EditorDefinition;

        public Dictionary<string, string> OtherColumns { get; set; }

        public override void Configure()
        {
            if (EditorDefinition is not CheckListEditor editor) return;
            Editor.ItemsPanel = GetItemsPanelTemplate(editor.Width);
            Editor.ItemContainerStyle = GetItemsContainerStyle(editor.ColumnWidth);
            Host.LoadLookups(this);
        }


        public override int DesiredHeight()
        {
            return 300;
        }

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

        public void LoadLookups(CoreTable otherfields)
        {
            _lookups = new Dictionary<object, string>();
            foreach (var row in otherfields.Rows)
                _lookups[row[ColumnName]] = row["Display"].ToString();
            SetupCheckListBox();
        }

        private class WidthConverter : AbstractConverter<double, double>
        {
            public CheckListEditorControl Parent { get; set; }
            
            public override double Convert(double value)
            {
                return value - 10.0;
            }
        }
        
        private ItemsPanelTemplate? GetItemsPanelTemplate(double width)
        {
	        FrameworkElementFactory fc = new FrameworkElementFactory(typeof(WrapPanel));
            var binding = new Binding()
            {
                RelativeSource = new RelativeSource(RelativeSourceMode.FindAncestor, typeof(CheckListBox), 1),
                Path = new PropertyPath(nameof(ActualWidth)),
                Converter = new WidthConverter() { Parent = this }
            };
            fc.SetBinding(WidthProperty,binding);
            //fc.SetValue(BackgroundProperty, new SolidColorBrush(Colors.LightBlue));
	        ItemsPanelTemplate ipt = new ItemsPanelTemplate(fc);
	        return ipt;
        }

        private Style? GetItemsContainerStyle(double width)
        {
            var style = new Style(typeof(CheckListBoxItem));                
            style.Setters.Add(new Setter {Property = WidthProperty, Value = width});
            //style.Setters.Add(new Setter {Property = BackgroundProperty, Value = new SolidColorBrush(Colors.Red)});
            return style;
        }
        
        
        protected override FrameworkElement CreateEditor()
        {
            
            Editor = new CheckListBox
            {
                DisplayMemberPath = "Value",
                SelectedValuePath = "Key",
                HorizontalAlignment = HorizontalAlignment.Stretch
            };
            //SkinStorage.SetVisualStyle(Editor, "Metro");
            Editor.SelectionChanged += (o, e) =>
            {
                if (!bLoading)
                    CheckChanged();
            };
            return Editor;
        }

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

        protected override Dictionary<string, bool> RetrieveValue()
        {
            _value = Activator.CreateInstance(_realtype) as Dictionary<string, bool>;
            foreach (KeyValuePair<object, string> pair in Editor.Items)
                _value[pair.Key.ToString()] = Editor.SelectedItems.Contains(pair);
            return _value;
        }

        protected override void UpdateValue(Dictionary<string, bool> value)
        {
            _realtype = value.GetType();
            _value = value;
            SetupCheckListBox();
        }

        public override void SetColor(Color color)
        {
            if (Editor.IsEnabled)
                Editor.Background = new SolidColorBrush(color);
            else
                _color = new SolidColorBrush(color);
        }


        private void SetupCheckListBox()
        {
            if (_lookups == null || _value == null || bLoading)
                return;
            bLoading = true;
            var sorted = _lookups.ToList();
            sorted.Sort((pair1, pair2) => pair1.Value.ToString().CompareTo(pair2.Value.ToString()));
            Editor.ItemsSource = sorted;

            if (_value != null)
            {
                foreach (var pair in sorted)
                {
                    var key = pair.Key.ToString();
                    if (_value.ContainsKey(key))
                    {
                        if (_value[key])
                            //Logger.Send(LogType.Information, "", String.Format("- Enabled: {0} / {1}", key, pair.Value));
                            Editor.SelectedItems.Add(pair);
                        //else
                        //Logger.Send(LogType.Information, "", String.Format("- Disabled: {0} / {1}", key, pair.Value));
                    }
                    else
                    {
                        //Logger.Send(LogType.Information, "",String.Format("- New Token: {0} / {1}",key,pair.Value));
                        Editor.SelectedItems.Add(pair);
                    }
                }

                Editor.IsEnabled = true;
                if (_color != null)
                    Editor.Background = _color;
            }

            bLoading = false;
        }
    }
}