using InABox.Core;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows;
using Syncfusion.Windows.Tools.Controls;
using Syncfusion.Data.Extensions;
using NPOI.SS.Formula.Functions;

namespace InABox.DynamicGrid
{
    public class MultiLookupEditorControl : DynamicEditorControl<object?, MultiLookupEditor>, ILookupEditorControl
    {

        static MultiLookupEditorControl()
        {
            //DynamicEditorControlFactory.Register<MultiLookupEditorControl, MultiLookupEditor>();
        }
        
        private ComboBoxAdv Editor;

        public MultiLookupEditorControl()
        {
            Lookups = new Dictionary<object, string>();
            Width = int.MaxValue;
        }

        public int Width { get; set; }

        private Dictionary<object, string> Lookups { get; set; }

        private List<Tuple<object?, string>> Items;

        public ILookupEditor LookupEditorDefinition => EditorDefinition;

        public override void Configure()
        {
            Editor.HorizontalAlignment = Width.Equals(int.MaxValue) ? HorizontalAlignment.Stretch : HorizontalAlignment.Left;
            if (!Width.Equals(int.MaxValue))
                Editor.Width = Width;
            Editor.IsEnabled = false;

            Host.LoadLookups(this);
        }

        public void LoadLookups(CoreTable values)
        {
            var keycol = ColumnName.Split('.').Last();
            //var prefix = string.Join(".", ColumnName.Split('.').Reverse().Skip(1).Reverse());

            /*foreach (var col in values.Columns)
                if (!string.Equals(col.ColumnName, keycol) && !string.Equals(col.ColumnName, "Display"))
                    if (!OtherColumns.ContainsKey(col.ColumnName))
                        OtherColumns[col.ColumnName] = string.IsNullOrWhiteSpace(prefix) ? col.ColumnName : string.Join(".", prefix, col.ColumnName);*/


            var value = RetrieveValue();

            //Lookups = lookups;

            Lookups.Clear();

            Items = new List<Tuple<object?, string>>();

            //if (!IsEnumEditor())
            //    Editor.Items.Add("");

            var selected = Editor.SelectedItems is not null ? Editor.SelectedItems.Cast<Tuple<object?, string>>().Select(x => x.Item1) : Enumerable.Empty<object?>();

            foreach (var row in values.Rows)
            {
                var key = row[keycol];
                Items.Add(new(key, $"{row["Display"]}"));
                if (key != null)
                {
                    Lookups[key] = string.Format("{0}", row["Display"]);
                }
            }
            Editor.ItemsSource = Items;
            Editor.DisplayMemberPath = "Item2";

            Editor.SelectedItems = Items.Where(x => selected.Contains(x.Item1)).ToObservableCollection();

            //var sel = values.Rows.FirstOrDefault(r => r[keycol].Equals(value));
            //if(sel is null)
            //if (IsEnumEditor())
            //    Editor.SelectedIndex = sel != null ? sel.Index : 0;
            //else
            //    Editor.SelectedIndex = sel != null ? sel.Index + 1 : 0;

            //foreach (var key in lookups.Keys)
            //    Editor.Items.Add(lookups[key]);
            //if ((value != null) && Lookups.ContainsKey(value))
            //    Editor.SelectedIndex = Lookups.Keys.ToList().IndexOf(value);

            Editor.IsEnabled = EditorDefinition.Editable.IsEditable();
        }

        public override int DesiredHeight()
        {
            return 25;
        }

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

        private bool IsEnumEditor()
        {
            return false;
        }

        public List<Button> Buttons { get; private set; }

        protected override FrameworkElement CreateEditor()
        {
            var dock = new DockPanel();


            Buttons = CreateButtons(out var DisableEditor);
            foreach (var button in Buttons)
            {
                button.SetValue(DockPanel.DockProperty, Dock.Right);
                dock.Children.Add(button);
                dock.Width += button.Width + 5;
            }

            Editor = new ComboBoxAdv
            {
                VerticalAlignment = VerticalAlignment.Stretch,
                VerticalContentAlignment = VerticalAlignment.Center,
                HorizontalAlignment = Width.Equals(int.MaxValue) ? HorizontalAlignment.Stretch : HorizontalAlignment.Left,
                IsEditable = false,
                AllowMultiSelect = true
            };

            Editor.SelectionChanged += Combobox_SelectionChanged;
            Editor.IsEnabled = false;

            if (DisableEditor)
            {
                Editor.Background = new SolidColorBrush(Colors.Silver);
                Editor.IsEnabled = false;
            }

            dock.Children.Add(Editor);

            return dock;
        }

        private void Combobox_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            if (!Editor.IsEnabled)
                return;

            /*if (LookupTable != null)
            {
                var keycol = ColumnName.Split('.').Last();

                var row = LookupTable.Rows.FirstOrDefault(r => object.Equals(r[keycol], RetrieveValue()));
                foreach (var field in LookupTable.Columns.Where(x => OtherColumns.ContainsKey(x.ColumnName)))
                {
                    var othervalue = row?[field.ColumnName];
                    OtherValues[OtherColumns[field.ColumnName]] = othervalue;
                }
            }*/

            CheckChanged();
        }

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

        protected override object? RetrieveValue()
        {
            if (Editor.SelectedIndex >= 0 && Editor.SelectedIndex < Lookups.Keys.Count)
                return string.Join(',', Editor.SelectedItems.Cast<Tuple<object?, string>>().Select(x => x.Item1));

            return "";
        }

        protected override void UpdateValue(object? value)
        {
            if (Editor == null)
                return;

            if (value == null)
            {
                Editor.SelectedItem = null;
                return;
            }

            if (!Loaded && !Editor.IsEnabled)
            {
                Lookups.Clear();
                Lookups[value] = "Loading";
                Editor.Items.Clear();
                Editor.Items.Add("");
                Editor.Items.Add("Loading...");
                Editor.SelectedIndex = IsEnumEditor() ? 0 : 1;
                return;
            }

            if(value is not string str)
            {
                return;
            }

            IEnumerable<Tuple<object?, string>> selected;
            if (!string.IsNullOrWhiteSpace(str))
            {
                var values = str.Split(',');
                selected = values.Select(x => Items.FirstOrDefault(y => y.Item1?.ToString() == x)).Where(x => x is not null)!;
            }
            else
            {
                selected = Enumerable.Empty<Tuple<object?, string>>();
            }

            Editor.SelectedItems = selected.ToObservableCollection();
            /*if (Lookups.ContainsKey(value))
            {
                if (IsEnumEditor())
                    Editor.SelectedIndex = Lookups.Keys.ToList().IndexOf(value);
                else
                    Editor.SelectedIndex = Lookups.Keys.ToList().IndexOf(value) + 1;
            }
            else
            {
                Editor.SelectedIndex = 0;
            }*/
        }

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

        public override void SetEnabled(bool enabled)
        {
            base.SetEnabled(enabled);

            Editor.IsEnabled = enabled;
        }
    }
}
