using System.Collections.Generic;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using InABox.Core;

namespace InABox.DynamicGrid
{
    public class LookupEditorControl : DynamicEditorControl<object, ILookupEditor>, ILookupEditorControl
    {
        
        static LookupEditorControl()
        {
            //DynamicEditorControlFactory.Register<LookupEditorControl, ILookupEditor, LookupEditor>();
            //DynamicEditorControlFactory.Register<LookupEditorControl, ILookupEditor, EnumLookupEditor>();
            //DynamicEditorControlFactory.Register<LookupEditorControl, ILookupEditor, ComboLookupEditor>();
        }
        
        private ComboBox Editor;

        private CoreTable LookupTable;

        private bool _loading = false;

        public ILookupEditor LookupEditorDefinition => EditorDefinition;

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

        public int Width { get; set; }

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

        private HashSet<string> OtherColumns { get; }

        public override void Configure()
        {
            if (Loaded)
                return;
            
            if (EditorDefinition.LookupWidth != int.MaxValue)
                Width = EditorDefinition.LookupWidth;

            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)
        {
            _loading = true;
            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"))
                    OtherColumns.Add(col.ColumnName);


            var value = RetrieveValue();

            //Lookups = lookups;
            LookupTable = values;


            Editor.Items.Clear();
            Lookups.Clear();

            if (!EditorDefinition.IsEnumEditor())
                Editor.Items.Add("");
            foreach (var row in values.Rows)
            {
                var display = row["Display"];
                Editor.Items.Add(display);

                var val = row[keycol];
                if (val is not null)
                {
                    Lookups[val] = display?.ToString() ?? "";
                }
            }

            var sel = value != null ? values.Rows.FirstOrDefault(r => r[keycol].Equals(value)) : null;
            if (EditorDefinition.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();
            _loading = false;
        }


        public override int DesiredHeight()
        {
            return 25;
        }

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

        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 ComboBox
            {
                VerticalAlignment = VerticalAlignment.Stretch,
                VerticalContentAlignment = VerticalAlignment.Center,
                HorizontalAlignment = Width.Equals(int.MaxValue) ? HorizontalAlignment.Stretch : HorizontalAlignment.Left
            };

            if (!Width.Equals(int.MaxValue))
                Width = Width;
            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 || _loading)
                return;

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

                var row = LookupTable.Rows.FirstOrDefault(r => Equals(r[keycol], value));
                foreach (var field in LookupTable.Columns.Where(x => OtherColumns.Contains(x.ColumnName)))
                {
                    OtherValues[field.ColumnName] = row?[field.ColumnName];
                }
            }

            CheckChanged();
        }

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

        protected override object RetrieveValue()
        {
            if (EditorDefinition.IsEnumEditor())
            {
                if (Editor.SelectedIndex >= 0 && Editor.SelectedIndex < Lookups.Keys.Count)
                    return Lookups.Keys.ElementAt(Editor.SelectedIndex);
            }
            else
            {
                if (Editor.SelectedIndex > 0 && Editor.SelectedIndex <= Lookups.Keys.Count)
                    return Lookups.Keys.ElementAt(Editor.SelectedIndex - 1);
            }

            return null;
        }

        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 = EditorDefinition.IsEnumEditor() ? 0 : 1;
                return;
            }

            if (Lookups.ContainsKey(value))
            {
                if (EditorDefinition.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;
        }
    }
}