using FasdDesktopUi.Basics.CustomEvents;
using FasdDesktopUi.Basics.Models;
using FasdDesktopUi.Basics.UiActions;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using static C4IT.Logging.cLogManager;

namespace FasdDesktopUi.Basics.UserControls
{
    public partial class CustomMenu : UserControl
    {
        #region Properties

        #region MenuDataList DependencyPoperty

        private static void MenuDataListChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            if (!(d is CustomMenu _me))
                return;

            _me.ClearControl();
            _me.AddCustomMenuItems();
            _me.UpdateCornerRadius();

            if (_me.IsKeyboardNavigatable)
                _me.IndexOfSelectedMenuItem = 0;
        }

        public static readonly DependencyProperty MenuDataListProperty =
            DependencyProperty.Register("MenuDataList", typeof(List<cMenuDataBase>), typeof(CustomMenu), new PropertyMetadata(new List<cMenuDataBase>(), new PropertyChangedCallback(MenuDataListChangedCallback)));

        public List<cMenuDataBase> MenuDataList
        {
            get { return (List<cMenuDataBase>)GetValue(MenuDataListProperty); }
            set { SetValue(MenuDataListProperty, value); }
        }

        #endregion

        #region IndexOfSelectedMenuItem DependencyProperty

        private static void IndexOfSelectedMenuItemChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            if (!(d is CustomMenu _me && e.NewValue is int index))
                return;

            if (!_me.IsKeyboardNavigatable)
                return;

            foreach (CustomMenuItem menuItem in _me.MainStackPanel.Children)
            {
                menuItem.MenuItemBorder.SetResourceReference(StyleProperty, "Menu.MainCategory");

                if (index < 0 || index > _me.MainStackPanel.Children.Count)
                    continue;

                if (_me.MainStackPanel.Children.IndexOf(menuItem) == index)
                    menuItem.MenuItemBorder.SetResourceReference(StyleProperty, "Menu.MainCategory.Hover");
            }
        }

        public static readonly DependencyProperty IndexOfSelectedMenuItemProperty =
            DependencyProperty.Register("IndexOfSelectedMenuItem", typeof(int), typeof(CustomMenu), new PropertyMetadata(-1, new PropertyChangedCallback(IndexOfSelectedMenuItemChanged)));

        public int IndexOfSelectedMenuItem
        {
            get { return (int)GetValue(IndexOfSelectedMenuItemProperty); }
            set { SetValue(IndexOfSelectedMenuItemProperty, value); }
        }

        #endregion

        #region IsKeyboardNavigatable

        public static readonly DependencyProperty IsKeyboardNavigatableProperty =
            DependencyProperty.Register("IsKeyboardNavigatable", typeof(bool), typeof(CustomMenuItem), new PropertyMetadata(false));

        public bool IsKeyboardNavigatable
        {
            get { return (bool)GetValue(IsKeyboardNavigatableProperty); }
            set { SetValue(IsKeyboardNavigatableProperty, value); }
        }

        #endregion

        #endregion

        public CustomMenu()
        {
            InitializeComponent();
        }

        public CustomMenu(bool drawWithBorder = false)
        {
            InitializeComponent();

            if (drawWithBorder)
                DrawControlWithBorder();
        }

        private void DrawControlWithBorder()
        {
            var tempBorder = new Border() { Padding = new Thickness(10), CornerRadius = new CornerRadius(10) };
            tempBorder.SetResourceReference(BackgroundProperty, "BackgroundColor.Menu.Categories");

            var tempControl = MainScrollViewer;
            MainGrid.Children.Remove(tempControl);

            MainGrid.Children.Add(tempBorder);
            tempBorder.Child = tempControl;
        }

        private void ClearControl()
        {
            MainStackPanel.Children.Clear();
            IndexOfSelectedMenuItem = -1;
        }

        private void AddCustomMenuItems()
        {
            if (MenuDataList == null)
                return;

            foreach (var menuItemData in MenuDataList)
            {
                var menuItem = new CustomMenuItem(false) { MenuData = menuItemData };
                menuItem.MouseEnter += MenuItem_MouseEnter;
                MainStackPanel.Children.Add(menuItem);
            }
        }

        private void UpdateCornerRadius()
        {
            const double cornerRadius = 10;

            if (MainStackPanel.Children.Count <= 0)
                return;

            if (MainStackPanel.Children[0] is CustomMenuItem menuItemFirst)
            {
                var tempCornerRadius = menuItemFirst.MenuItemBorder.CornerRadius;
                tempCornerRadius.TopLeft = cornerRadius;
                tempCornerRadius.TopRight = cornerRadius;
                menuItemFirst.MenuItemBorder.CornerRadius = tempCornerRadius;
            }

            if (MainStackPanel.Children[MainStackPanel.Children.Count - 1] is CustomMenuItem menuItemLast)
            {
                var tempCornerRadiusLast = menuItemLast.MenuItemBorder.CornerRadius;
                tempCornerRadiusLast.BottomLeft = cornerRadius;
                tempCornerRadiusLast.BottomRight = cornerRadius;
                menuItemLast.MenuItemBorder.CornerRadius = tempCornerRadiusLast;
            }
        }

        private void MenuItem_MouseEnter(object sender, MouseEventArgs e)
        {
            if (!(sender is CustomMenuItem menuItem))
                return;

            CustomEventManager.RaiseIndexChangedEvent(this, -1, MainStackPanel.Children.IndexOf(menuItem));
        }

        internal void ShowDetailHeading(bool showDetailHeadings)
        {
            try
            {
                foreach (var resultItem in MainStackPanel.Children.OfType<CustomMenuItem>())
                {
                    resultItem.ShowDetailHeadings(showDetailHeadings);
                }
            }
            catch (Exception ex)
            {
                LogException(ex);
            }
        }

        internal void HightlightItemAt(int index)
        {
            try
            {
                foreach (CustomMenuItem resultItem in MainStackPanel.Children)
                {
                    if (MainStackPanel.Children.IndexOf(resultItem) == index)
                    {
                        resultItem.MenuItemBorder.SetResourceReference(StyleProperty, "Menu.MainCategory.Hover");
                        CustomEventManager.RaiseMenuDataChangedEvent(this, resultItem.MenuData);
                    }
                    else
                        resultItem.MenuItemBorder.SetResourceReference(StyleProperty, "Menu.MainCategory");
                }
            }
            catch (Exception ex)
            {
                LogException(ex);
            }
        }

        internal void SelectItemAt(int index)
        {
            try
            {
                if (MenuDataList is null)
                    return;

                if (index < 0)
                    return;

                if (MenuDataList.Count == 0 || MenuDataList.Count <= index)
                    return;

                cUiActionBase uiAction = MenuDataList[index].UiAction;

                if (uiAction is null || uiAction.DisplayType == Enums.enumActionDisplayType.disabled)
                    return;

                cUiActionBase.RaiseEvent(uiAction, this, this);
            }
            catch (Exception E)
            {
                LogException(E);
            }
        }
    }
}
