using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Interop;

using FasdDesktopUi.Basics;
using FasdDesktopUi.Basics.Models;
using FasdDesktopUi.Basics.UiActions;
using FasdDesktopUi.Basics.UserControls;
using FasdDesktopUi.Pages.SlimPage.Models;

using C4IT.FASD.Base;
using C4IT.MultiLanguage;
using static C4IT.Logging.cLogManager;
using System.Diagnostics;
using System.Threading.Tasks;
using F4SD_AdaptableIcon.Enums;

namespace FasdDesktopUi.Pages.SlimPage
{
    public partial class SlimPageView : SupportCasePageBase, IBlurrable
    {
        #region Properties

        private bool shouldReRunDataChangedEvent = false;

        private const int MaxItemCountMenuBar = 5;

        #endregion

        #region Blurring

        internal override void DoBlurredChanged(bool isBlured)
        {
            DataHistoryCollectionUc.IsBlurred = isBlured;
            WidgetCollectionUc.IsBlurred = isBlured;
        }

        internal override bool CheckBlurInvoker(IBlurInvoker invoker)
        {
            try
            {
                switch (invoker)
                {
                    case SearchBar searchBar:
                        if (!searchBar.IsVisible || searchBar.SearchStatus != SearchBar.eSearchStatus.message)
                            return true;
                        break;
                    case QuickActionSelector _:
                    case QuickActionStatusMonitor _:
                        return true;
                    default:
                        break;
                }

            }
            catch (Exception E)
            {
                LogException(E);
            }
            return false;
        }

        #endregion

        public SlimPageView()
        {
            try
            {
                InitializeComponent();

                AddCustomHandlers();

                SourceInitialized += (s, e) =>
                {
                    IntPtr handle = new WindowInteropHelper(this).Handle;
                    HwndSource.FromHwnd(handle).AddHook(new HwndSourceHook(cUtility.WindowProc));
                };

                UiSettingsChanged(null, null);
            }
            catch (Exception E)
            {
                LogException(E);
            }
        }

        private void SlimPage_Loaded(object sender, RoutedEventArgs e)
        {
            MenuBarUc.SetSlimPage();
        }

        private void AddCustomHandlers()
        {
            try
            {
                AddHandler(cUiActionBase.UiActionClickedEvent, new cUiActionBase.UiActionEventHandlerDelegate(UiActionWasTriggered));
                AddHandler(DataCanvas.DataCanvasWasClosedEvent, new RoutedEventHandler(DataCanvasWasClosed));

                BlurInvoker.BlurInvokerVisibilityChanged += (obj, e) => UpdateBlurStatus(obj);

                MenuBarUc.SearchButtonClickedAction = SearchButtonClickedAction;
                MenuBarUc.MoreButtonClickedAction = MoreButtonClickedAction;

                SearchBarUserControl.ChangedSearchValue = EnteredSearchValueAsync;
                SearchBarUserControl.CancledSearchAction = BlurBorder_Click;

                cFasdCockpitConfig.Instance.UiSettingsChanged += UiSettingsChanged;
                cConnectionStatusHelper.ApiConnectionStatusChanged += ApiConnectionStatusChanged;
            }
            catch (Exception E)
            {
                LogException(E);
            }
        }

        private void UiSettingsChanged(object sender, EventArgs e)
        {
            try
            {
                var positionAlignement = cFasdCockpitConfig.Instance.Global.SmallViewAlignment;

                switch (positionAlignement)
                {
                    case enumF4sdHorizontalAlignment.Center:
                        MainBorder.HorizontalAlignment = HorizontalAlignment.Center;
                        break;
                    case enumF4sdHorizontalAlignment.Right:
                        MainBorder.HorizontalAlignment = HorizontalAlignment.Right;
                        break;
                    default:
                        MainBorder.HorizontalAlignment = HorizontalAlignment.Left;
                        break;
                }
            }
            catch (Exception E)
            {
                LogException(E);
            }
        }

        private void ApiConnectionStatusChanged(cConnectionStatusHelper.enumOnlineStatus? Status)
        {

            try
            {
                if (Status == cConnectionStatusHelper.enumOnlineStatus.online)
                {
                    Dispatcher.Invoke(() =>
                    {
                        Footer.ClearValue(IsHitTestVisibleProperty);
                        Footer.ClearValue(OpacityProperty);
                        DynamicBodyParts.ClearValue(IsHitTestVisibleProperty);
                        DynamicBodyParts.ClearValue(OpacityProperty);
                        if (MenuBarUc.Visibility != Visibility.Visible)
                        {
                            SearchBarUserControl.Visibility = Visibility.Collapsed;
                            MenuBarUc.Visibility = Visibility.Visible;
                        }
                    });
                }
                else
                {
                    Dispatcher.Invoke(() =>
                    {
                        Footer.IsHitTestVisible = false;
                        DynamicBodyParts.IsHitTestVisible = false;
                        DynamicBodyParts.Opacity = 0.6;
                        if (SearchBarUserControl.Visibility != Visibility.Visible)
                        {
                            MenuBarUc.Visibility = Visibility.Collapsed;
                            SearchBarUserControl.Visibility = Visibility.Visible;
                        }
                        SearchBarUserControl.SetApiStatus();

                        IsBlurred = true;
                    });
                }
            }
            catch (Exception E)
            {
                LogException(E);
            }
            finally
            {
            }

        }

        #region Delegate Actions

        private void SearchButtonClickedAction()
        {

            try
            {
                MenuBarUc.MenuBarUc.Visibility = Visibility.Collapsed;
                SearchBarUserControl.Visibility = Visibility.Visible;
                SearchBarUserControl.ActivateManualSearch();

                DynamicBodyParts.Child = null;
            }
            catch (Exception E)
            {
                LogException(E);
            }
        }

        private async Task EnteredSearchValueAsync(cFilteredResults filteredResults)
        {
            await Task.CompletedTask;
            //try
            //{
            //    if (filteredResults?.Results == null)
            //    {
            //        DynamicBodyParts.Child = null;
            //        return;
            //    }

            //    if (DynamicBodyParts.Child is CustomSearchResultCollection customSearchResultCollection)
            //    {
            //        customSearchResultCollection.ShowSearchResults(filteredResults,null);
            //        customSearchResultCollection.IndexOfSelectedResultItem = filteredResults?.Results?.Count - 1 ?? -1;
            //    }
            //    else
            //    {
            //        var _searchResultCollection = new CustomSearchResultCollection(true) { IndexOfSelectedResultItem = filteredResults?.Results?.Count - 1 ?? -1 };
            //        _searchResultCollection.ShowSearchResults(filteredResults,null);
            //        DynamicBodyParts.Child = _searchResultCollection;
            //    }
            //}
            //catch (Exception E)
            //{
            //    LogException(E);
            //}
        }

        private void MoreButtonClickedAction()
        {
            try
            {
                if (!(DataContext is SlimPageViewModel viewModel))
                    return;

                var tempMoreQuickActionList = viewModel.MenuDrawerData;

                if (cF4SDCockpitXmlConfig.Instance?.CopyTemplateConfig?.CopyTemplates != null)
                {
                    var tempSubMenuList = new List<cMenuDataBase>();

                    foreach (var copyTemplate in cF4SDCockpitXmlConfig.Instance?.CopyTemplateConfig?.CopyTemplates.CopyTemplates)
                    {
                        tempSubMenuList.Add(new cMenuDataBase(copyTemplate.Value));
                    }

                    tempMoreQuickActionList.Insert(0, new cMenuDataContainer() { MenuText = cMultiLanguageSupport.GetItem("QuickAction.CopyContent"), MenuIcon = new F4SD_AdaptableIcon.IconData(enumInternIcons.menuBar_copy), UiAction = new cSubMenuAction(true) { Name = cMultiLanguageSupport.GetItem("QuickAction.CopyContent"), SubMenuData = tempSubMenuList }, SubMenuData = tempSubMenuList });
                }

                var quickActionSelector = new QuickActionSelector()
                {
                    Visibility = Visibility.Visible,
                    QuickActionList = tempMoreQuickActionList,
                    QuickActionSelectorHeading = "Quick Actions",
                    TempQuickActionList = null,
                    CloseButtonClickedAction = BlurBorder_Click
                };

                quickActionSelector.LockButton.Visibility = Visibility.Collapsed;
                DynamicBodyParts.Child = quickActionSelector;
            }
            catch (Exception E)
            {
                LogException(E);
            }
        }

        #endregion

        public void SetPropertyValues(cSlimPageData slimPageData)
        {
            try
            {
                BlurBorder_Click();

                if (DataContext is SlimPageViewModel viewModel)
                    viewModel.InitializeProperties(slimPageData);

                //todo: replace binding with following schema due to performance issues:
                WidgetCollectionUc.HeadingData = slimPageData.HeadingData;
                WidgetCollectionUc.WidgetData = slimPageData.WidgetData;
            }
            catch (Exception E)
            {
                LogException(E);
            }
        }

        #region Update Data

        internal override async void DataProvider_DataChanged(object sender, EventArgs e)
        {
            try
            {
                if (isDataChangedEventRunning)
                {
                    shouldReRunDataChangedEvent = true;
                    return;
                }

                var data = await _supportCaseController?.SupportCaseDataProviderArtifact.HealthCardDataHelper.SlimCard.GetDataAsync();
                //todo: check if there is a more performant way solving this
                Dispatcher.Invoke(() => WidgetCollectionUc.HeadingData = data.HeadingData);
                Dispatcher.Invoke(() => WidgetCollectionUc.WidgetData = data.WidgetData);
                Dispatcher.Invoke(() => MenuBarUc.MenuBarItemData = GetSlimpageMenuBarData(data.MenuBarData));
                Dispatcher.Invoke(() => DataHistoryCollectionUc.UpdateHistory(data.DataHistoryList));

                Dispatcher.Invoke(() =>
                {
                    if (DataContext is SlimPageViewModel viewModel)
                        viewModel.InitializeProperties(data);
                });

                if (shouldReRunDataChangedEvent)
                {
                    shouldReRunDataChangedEvent = false;
                    DataProvider_DataChanged(sender, e);
                }
            }
            catch (Exception E)
            {
                LogException(E);
            }
        }

        internal override async void DataProvider_DataFullyLoaded(object sender, EventArgs e)
        {
            try
            {
                var data = await _supportCaseController?.SupportCaseDataProviderArtifact.HealthCardDataHelper.SlimCard.GetDataAsync();
                //todo: check if there is a more performant way solving this
                Dispatcher.Invoke(() => WidgetCollectionUc.HeadingData = data.HeadingData);
                Dispatcher.Invoke(() => WidgetCollectionUc.WidgetData = data.WidgetData);
                Dispatcher.Invoke(() => MenuBarUc.MenuBarItemData = GetSlimpageMenuBarData(data.MenuBarData));
                Dispatcher.Invoke(() => DataHistoryCollectionUc.UpdateHistory(data.DataHistoryList));

                if (_supportCaseController != null)
                {
                    _supportCaseController.SupportCaseDataProviderArtifact.HealthCardDataHelper.LoadingHelper.DataChanged -= DataProvider_DataChanged;
                    _supportCaseController.SupportCaseDataProviderArtifact.HealthCardDataHelper.LoadingHelper.DataFullyLoaded -= DataProvider_DataFullyLoaded;
                }
            }
            catch (Exception E)
            {
                LogException(E);
            }
        }

        internal override void DirectConnectionHelper_DirectConnectionChanged(object sender, EventArgs e)
        {
            try
            {
                Dispatcher.Invoke(() =>
                {
                    bool hasDirectConnection = _supportCaseController?.SupportCaseDataProviderArtifact?.DirectConnectionHelper?.IsDirectConnectionActive ?? false;
                    WidgetCollectionUc.HasDirectConnection = hasDirectConnection;
                });
            }
            catch (Exception E)
            {
                LogException(E);
            }
        }

        private List<cMenuDataBase> GetSlimpageMenuBarData(List<cMenuDataBase> list)
        {
            try
            {
                list.Where(data => data.IconPositionIndex > -1)
                    .OrderBy(data => data.IconPositionIndex)
                    .Skip(MaxItemCountMenuBar)
                    .ToList()
                    .ForEach(data => data.IconPositionIndex = -1);
                return list;
            }
            catch (Exception E)
            {
                LogException(E);
            }
            return new List<cMenuDataBase>();
        }

        #endregion

        #region BlurBorder_Click

        private void BlurBorder_Click()
        {
            try
            {
                if (!(DataContext is SlimPageViewModel viewModel))
                    return;

                if (SearchBarUserControl.SearchStatus != SearchBar.eSearchStatus.message)
                {
                    SearchBarUserControl.Visibility = Visibility.Collapsed;
                    MenuBarUc.Visibility = Visibility.Visible;
                }
                else
                    IsBlurred = false;

                DynamicBodyParts.Child = null;
            }
            catch (Exception E)
            {
                LogException(E);
            }
        }

        private void BlurBorder_MouseUp(object sender, MouseButtonEventArgs e)
        {
            BlurBorder_Click();
        }

        private void BlurBorder_TouchDown(object sender, TouchEventArgs e)
        {
            BlurBorder_Click();
        }

        #endregion

        #region Search Events

        private void SearchBar_DidSearch(object sender, RoutedEventArgs e)
        {
            BlurBorder_Click();
        }

        private void SearchBar_CancledSearch(object sender, RoutedEventArgs e)
        {
            BlurBorder_Click();
        }

        #endregion

        #region WindowStateBar Events

        private void WindowStateBarUc_ClickedClose(object sender, RoutedEventArgs e)
        {
            BlurBorder_Click();
            Close();
        }

        private void WindowStateBarUc_ClickedMaximize(object sender, RoutedEventArgs e)
        {
            try
            {
                var detailsPage = cSupportCaseDataProvider.detailsPage;

                if (detailsPage != null)
                {
                    Hide();
                    App.HideAllSettingViews();
                    detailsPage.Show();
                }
            }
            catch (Exception E)
            {
                LogException(E);
            }
        }

        #endregion

        private async void UiActionWasTriggered(object sender, UiActionEventArgs e)
        {
            try
            {
                // define drawing area            
                UIElement drawingArea = null;

                switch (e.UiAction)
                {
                    case cUiQuickAction _:
                        drawingArea = DynamicBodyParts.Child is Decorator decorator ? decorator : new Decorator();
                        if (!(DynamicBodyParts.Child is Decorator))
                            DynamicBodyParts.Child = drawingArea;
                        break;
                    case cSubMenuAction _:
                        drawingArea = DynamicBodyParts.Child is QuickActionSelector quickActionSelector ? quickActionSelector : new QuickActionSelector();
                        if (!(DynamicBodyParts.Child is QuickActionSelector))
                            DynamicBodyParts.Child = drawingArea;
                        break;
                }

                await e.UiAction?.RunUiActionAsync(e.OriginalSource, drawingArea, false, _supportCaseController?.SupportCaseDataProviderArtifact);

            }
            catch (Exception E)
            {
                LogException(E);
            }
        }

        private void DataCanvasWasClosed(object sender, RoutedEventArgs e)
        {
            BlurBorder_Click();
        }

        private void Window_PreviewKeyDown(object sender, KeyEventArgs e)
        {
            try
            {
                if (SearchBarUserControl.Visibility == Visibility.Visible && DynamicBodyParts.Child is CustomSearchResultCollection resultMenu)
                {
                    switch (e.Key)
                    {
                        case Key.Up:
                            if (resultMenu.IndexOfSelectedResultItem > 0)
                                resultMenu.IndexOfSelectedResultItem--;
                            break;
                        case Key.Down:
                            resultMenu.IndexOfSelectedResultItem++;
                            break;
                        case Key.Enter:
                            resultMenu.SelectCurrentResultItem();
                            e.Handled = true;
                            break;
                        case Key.Escape:
                            BlurBorder_Click();
                            break;
                    }

                    return;
                }
                else
                {
                    switch (e.Key)
                    {
                        case Key.Enter:
                            if (SearchBarUserControl.Visibility == Visibility.Visible)
                                break;

                            var detailsPage = cSupportCaseDataProvider.detailsPage;
                            if (detailsPage != null)
                            {
                                Hide();
                                App.HideAllSettingViews();
                                detailsPage.Show();
                            }
                            break;
                        case Key.F3:
                            if (Keyboard.Modifiers == ModifierKeys.Control)
                                SearchButtonClickedAction();
                            break;
                    }
                } //todo: add QuickAction Navigation
            }
            catch (Exception E)
            {
                LogException(E);
            }
        }

        public void SetZoomValue(int zoomInPercent)
        {
            try
            {
                if (DataContext is SlimPageViewModel viewModel)
                    viewModel.ZoomInPercent = zoomInPercent;
            }
            catch (Exception E)
            {
                LogException(E);
            }
        }
    }
}
