using FasdDesktopUi.Basics.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using static C4IT.Logging.cLogManager;

namespace FasdDesktopUi.Basics.UserControls
{
    public partial class EditWidgetValueControl : UserControl, IFocusInvoker
    {
        #region Properties and fields

        private object originalValue;
        private bool isValueChanged = false;
        private Action setFocus;

        public int? ParentIndex { get; set; }

        public UIElement ParentElement { get; set; }

        #region EditableValueInformation

        public cEditableValueInformationBase EditableValueInformation
        {
            get { return (cEditableValueInformationBase)GetValue(EditableValueInformationProperty); }
            set { SetValue(EditableValueInformationProperty, value); }
        }

        public static readonly DependencyProperty EditableValueInformationProperty =
            DependencyProperty.Register("EditableValueInformation", typeof(cEditableValueInformationBase), typeof(EditWidgetValueControl), new PropertyMetadata(null, new PropertyChangedCallback(EditableValueChanged)));

        private static void EditableValueChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            try
            {
                if (!(d is EditWidgetValueControl _me))
                    return;

                _me.originalValue = _me.EditableValueInformation.CurrentValue;
                _me.UpdateEditControlBorder();
            }
            catch (Exception E)
            {
                LogException(E);
            }
        }

        #endregion

        #endregion

        public EditWidgetValueControl()
        {
            InitializeComponent();
        }

        private void UpdateEditControlBorder()
        {
            try
            {
                switch (EditableValueInformation)
                {
                    case cEditValueInformationSelection editSelectionInformation:
                        {
                            if (editSelectionInformation.SelectionValues is null || editSelectionInformation.SelectionValues?.Count <= 0)
                                return;

                            ComboBox editComboBox = new ComboBox();
                            foreach (var listValue in editSelectionInformation.SelectionValues)
                            {
                                ComboBoxItem tempComboBoxItem = new ComboBoxItem() { Content = listValue.Value, Tag = listValue.Key };
                                editComboBox.Items.Add(tempComboBoxItem);
                            }

                            var currentSelectedValue = editSelectionInformation.SelectionValues.FirstOrDefault(value => value.Key?.Equals(editSelectionInformation.CurrentValue) ?? false);
                            editComboBox.SelectedIndex = editSelectionInformation.SelectionValues.IndexOf(currentSelectedValue);

                            editComboBox.DropDownOpened += (sender, e) => cFocusInvoker.InvokeGotFocus(this, e);
                            editComboBox.DropDownClosed += (sender, e) => cFocusInvoker.InvokeLostFocus(this, e);
                            editComboBox.SelectionChanged += (sender, e) =>
                            {
                                if (editComboBox.SelectedItem is FrameworkElement selectedElement)
                                    UpdateEditIcon(selectedElement.Tag);
                            };

                            EditControlBorder.Child = editComboBox;
                            EditButton.Visibility = Visibility.Collapsed;
                        }
                        break;
                    case cEditValueInformationText editTextInformation:
                        {
                            if (editTextInformation.CurrentValue is null)
                                return;

                            TextBox editTextBox = new TextBox() { Text = editTextInformation.CurrentValue.ToString() };
                            editTextBox.TextChanged += (sender, e) => UpdateEditIcon(editTextBox.Text);
                            EditButton.Visibility = Visibility.Visible;
                            EditControlBorder.Child = editTextBox;

                            setFocus = (() =>
                            {
                                editTextBox.Focus();
                                editTextBox.Select(0, editTextBox.Text.Length);
                            });
                        }
                        break;
                    default:
                        break;
                }
            }
            catch (Exception E)
            {
                LogException(E);
            }
        }

        private void UpdateEditIcon(object newValue)
        {
            try
            {
                if (originalValue is null || newValue is null)
                    return;

                isValueChanged = originalValue.ToString().Equals(newValue.ToString(), StringComparison.InvariantCultureIgnoreCase) is false;

                if (isValueChanged)
                    EditButton.SelectedMaterialIcon = MaterialIcons.MaterialIconType.ic_undo;
                else
                    EditButton.SelectedMaterialIcon = MaterialIcons.MaterialIconType.ic_edit;
            }
            catch (Exception E)
            {
                LogException(E);
            }
        }

        #region Evetns

        #region EditButton_Click        

        private void EditButton_Click()
        {
            if (isValueChanged)
            {
                UpdateEditControlBorder();
                UpdateEditIcon(originalValue);
            }
            else
            {
                setFocus?.Invoke();
            }
        }

        private void EditButton_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
        {
            EditButton_Click();
        }

        private void EditButton_TouchDown(object sender, TouchEventArgs e)
        {
            EditButton_Click();
        }

        #endregion

        #endregion


    }
}
