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 C4IT.FASD.Base;
using C4IT.Logging;

using F4SD_AdaptableIcon.Enums;

using FasdDesktopUi.Basics.Enums;
using FasdDesktopUi.Basics.Models;
using FasdDesktopUi.Basics.UiActions;
using FasdDesktopUi.Basics.UserControls;
using FasdDesktopUi.Basics.UserControls.AdaptableIcon;
using FasdDesktopUi.Pages.DetailsPage.Models;

using static C4IT.Logging.cLogManager;

namespace FasdDesktopUi.Pages.DetailsPage.UserControls
{
    public partial class DetailsPageDataHistoryTitleColumn : UserControl
    {
        #region Properties

        #region SubtitleCount DependencyProperty

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

            _me.ClearControls();
            _me.InitializeOverviewTitle();
            _me.InitializeSubtitleControls((int)e.NewValue);
        }

        public static readonly DependencyProperty SubtitleCountProperty =
            DependencyProperty.Register("SubtitleCount", typeof(int), typeof(DetailsPageDataHistoryTitleColumn), new PropertyMetadata(-1, new PropertyChangedCallback(SubtitleCountChangedCallback)));

        public int SubtitleCount
        {
            get { return (int)GetValue(SubtitleCountProperty); }
            set { SetValue(SubtitleCountProperty, value); }
        }

        #endregion

        #region ColumnValues DependencyProperty

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

            var updatedColumnValues = (DetailsPageDataHistoryColumnModel)e.NewValue;
            _me.UpdateColumnSize(updatedColumnValues.ColumnValues.Count - _me.MainGrid.RowDefinitions.Count);
            _me.RefreshOverviewTitle(updatedColumnValues);
            _me.RefreshSubtitleSection(updatedColumnValues);
        }

        public static readonly DependencyProperty ColumnValuesProperty =
            DependencyProperty.Register("ColumnValues", typeof(DetailsPageDataHistoryColumnModel), typeof(DetailsPageDataHistoryTitleColumn), new PropertyMetadata(new DetailsPageDataHistoryColumnModel(), new PropertyChangedCallback(ColumnValuesChangedCallback)));

        public DetailsPageDataHistoryColumnModel ColumnValues
        {
            get { return (DetailsPageDataHistoryColumnModel)GetValue(ColumnValuesProperty); }
            set { SetValue(ColumnValuesProperty, value); }
        }

        #endregion

        #endregion

        #region Controls

        public TextBlock TitleOverviewControl;
        private FunctionMarker TitleOverviewFunctionMarker;
        private readonly List<FrameworkElement> SubtitleValueControls = new List<FrameworkElement>();
        private readonly List<FunctionMarker> SubtitleFunctionMarkers = new List<FunctionMarker>();

        private void ClearControls()
        {
            try
            {
                foreach (var functionMarker in SubtitleFunctionMarkers)
                {
                    if (functionMarker.Parent is FrameworkElement functionMarkerParent)
                        MainGrid.Children.Remove(functionMarkerParent);
                }

                SubtitleValueControls.Clear();
                SubtitleFunctionMarkers.Clear();

                if (MainGrid.RowDefinitions.Count > 0)
                    MainGrid.RowDefinitions.Clear();
            }
            catch (Exception E)
            {
                cLogManager.LogException(E);
            }
        }

        #region Initialize Controls

        private void InitializeOverviewTitle()
        {
            if (TitleOverviewControl != null)
                return;

            DockPanel titleDockPanel = new DockPanel();

            TextBlock titleTextBlock = new TextBlock() { Style = titleColumnOverViewTitleStyle };

            TitleOverviewControl = titleTextBlock;
            TitleOverviewFunctionMarker = FunctionMarker.SetUpFunctionMarker(titleDockPanel, new FunctionMarker.FunctionMarkerClick(FunctionMarker_Click), selectedMarker: enumInternIcons.misc_functionBolt, isTitleFunctionMarker: true);
            TitleOverviewFunctionMarker.Cursor = Cursors.Hand;
            DockPanel.SetDock(TitleOverviewFunctionMarker, Dock.Left);

            titleDockPanel.Children.Add(titleTextBlock);

            TitleRowBorder.Child = titleDockPanel;
        }

        private void InitializeSubtitleRow(int rowIndex)
        {
            MainGrid.RowDefinitions.Add(new RowDefinition() { Height = new GridLength(35) });

            StackPanel subTitleStackPanel = new StackPanel() { Orientation = Orientation.Horizontal, HorizontalAlignment = HorizontalAlignment.Right };
            TextBlock subTitleTextBlock = new TextBlock() { Style = titleColumnMainTitleStyle };
            SubtitleValueControls.Add(subTitleTextBlock);

            SubtitleFunctionMarkers.Add(FunctionMarker.SetUpFunctionMarker(subTitleStackPanel, new FunctionMarker.FunctionMarkerClick(FunctionMarker_Click), selectedMarker: enumInternIcons.misc_functionBolt));
            subTitleStackPanel.Children.Add(subTitleTextBlock);

            Grid.SetRow(subTitleStackPanel, rowIndex);
            MainGrid.Children.Add(subTitleStackPanel);
        }

        private void InitializeSubtitleControls(int subtitleCount)
        {
            for (int i = 0; i < subtitleCount; i++)
            {
                try
                {
                    InitializeSubtitleRow(i);
                }
                catch (Exception E)
                {
                    cLogManager.LogException(E);
                }
            }
        }

        private void FunctionMarker_Click(object sender)
        {
            if (!(sender is FrameworkElement FE))
                return;

            if (!(FE.Tag is cDataHistoryValueModel HistorySubtitleValue))
                return;

            if (HistorySubtitleValue.UiAction == null)
                return;
            cUiActionBase.RaiseEvent(HistorySubtitleValue.UiAction, this, this);
        }

        #endregion

        private void UpdateColumnSize(int rowsToAdd)
        {
            if (rowsToAdd > 0)
            {
                int rowIndex = MainGrid.RowDefinitions.Count;

                for (int i = rowIndex; i < rowsToAdd + rowIndex; i++)
                {
                    InitializeSubtitleRow(i);
                }
            }
            else
            {
                MainGrid.RowDefinitions.ToList().ForEach(rowDefinitions => rowDefinitions.Height = new GridLength(35));

                var reversedRowList = MainGrid.RowDefinitions.Reverse().ToList();
                for (int i = 0; i < Math.Abs(rowsToAdd); i++)
                {
                    reversedRowList[i].Height = new GridLength(0);
                }
            }
        }

        #region Refresh Values

        private void RefreshOverviewTitle(DetailsPageDataHistoryColumnModel columnData)
        {
            try
            {
                if (TitleOverviewControl is null)
                {
                    LogEntry("The title overview control wasn't instantiated.", LogLevels.Error);
                    return;
                }

                //OverviewTitle Control
                TitleOverviewControl.Text = columnData.Content;
                TitleOverviewControl.ToolTip = columnData.ContentDescription;
                TitleRowBorder.ToolTip = columnData.ContentDescription;

                //Functionmarker
                if (columnData.UiAction != null)
                {
                    TitleOverviewFunctionMarker.Visibility = Visibility.Visible;
                    TitleOverviewFunctionMarker.Tag = columnData;

                    var tempToolTip = columnData.UiAction.Name;
                    if (!string.IsNullOrEmpty(columnData.UiAction.Description))
                        tempToolTip += ": \n" + columnData.UiAction.Description;

                    TitleOverviewFunctionMarker.ToolTip = tempToolTip;
                }
                else
                {
                    TitleOverviewFunctionMarker.Visibility = Visibility.Hidden;
                    TitleOverviewFunctionMarker.ClearValue(TagProperty);
                    TitleOverviewFunctionMarker.ClearValue(ToolTipProperty);
                }
            }
            catch (Exception E)
            {
                cLogManager.LogException(E);
            }
        }

        private void RefreshSubtitleValues(DetailsPageDataHistoryColumnModel columnData)
        {
            var dataEnumerator = columnData.ColumnValues.GetEnumerator();

            foreach (var subtitleControl in SubtitleValueControls)
            {
                try
                {
                    if (!dataEnumerator.MoveNext())
                        return;

                    if (!(subtitleControl is TextBlock subtitleTextBlock))
                        return;

                    bool hasRecommendation = dataEnumerator.Current.ContentDescription != null && dataEnumerator.Current.Content != dataEnumerator.Current.ContentDescription;

                    subtitleTextBlock.Text = dataEnumerator.Current.Content;

                    subtitleTextBlock.Cursor = hasRecommendation ? Cursors.Hand : null;
                    if (!hasRecommendation)
                        subtitleTextBlock.SetResourceReference(ForegroundProperty, dataEnumerator.Current.PresentationStyle == enumHistoryTitleType.subValue ? "FontColor.DetailsPage.DataHistory.TitleColumn.SubTitle" : "FontColor.DetailsPage.DataHistory.TitleColumn.MainTitle");

                    subtitleTextBlock.Style = dataEnumerator.Current.PresentationStyle == enumHistoryTitleType.subValue ? titleColumnSubTitleStyle : titleColumnMainTitleStyle;
                    subtitleTextBlock.FontWeight = dataEnumerator.Current.PresentationStyle == enumHistoryTitleType.aggregate ? FontWeights.Bold : FontWeights.Normal;
                    subtitleTextBlock.Visibility = Visibility.Visible;

                    subtitleTextBlock.Tag = dataEnumerator.Current;
                    subtitleTextBlock.MouseLeftButtonUp += TitleMouseLeftButtonUpEvent;
                    subtitleTextBlock.TouchDown += TitleTouchedEvent;
                }
                catch (Exception E)
                {
                    cLogManager.LogException(E);
                }
            }
        }

        #region Title Click Event

        private void Title_Click(object sender)
        {
            if (!(sender is FrameworkElement FE))
                return;

            if (!(FE.Tag is cDataHistoryValueModel HistorySubtitleValue))
                return;

            if (string.IsNullOrEmpty(HistorySubtitleValue.ContentDescription) || HistorySubtitleValue.ContentDescription == HistorySubtitleValue.Content)
                return;

            cUiActionBase uiAction = new cShowRecommendationAction(HistorySubtitleValue.Content, HistorySubtitleValue.ContentDescription);
            cUiActionBase.RaiseEvent(uiAction, this, this);
        }

        private void TitleMouseLeftButtonUpEvent(object sender, MouseButtonEventArgs e)
        {
            Title_Click(sender);
        }
        private void TitleTouchedEvent(object sender, TouchEventArgs e)
        {
            Title_Click(sender);
        }

        #endregion

        private void RefreshSubtitleFunctionmarker(DetailsPageDataHistoryColumnModel columnData)
        {
            var dataEnumerator = columnData.ColumnValues.GetEnumerator();

            foreach (var functionMarker in SubtitleFunctionMarkers)
            {
                try
                {
                    if (!dataEnumerator.MoveNext())
                        return;

                    if (dataEnumerator.Current.UiAction != null && dataEnumerator.Current.UiAction.DisplayType == enumActionDisplayType.enabled && !(dataEnumerator.Current.UiAction is cShowDetailedDataAction))
                    {
                        functionMarker.Visibility = Visibility.Visible;
                        functionMarker.Tag = dataEnumerator.Current;

                        var tempToolTip = dataEnumerator.Current.UiAction.Name;
                        if (!string.IsNullOrEmpty(dataEnumerator.Current.UiAction.Description))
                            tempToolTip += ": \n" + dataEnumerator.Current.UiAction.Description;

                        functionMarker.ToolTip = tempToolTip;
                    }
                    else
                    {
                        functionMarker.Visibility = Visibility.Collapsed;
                        functionMarker.ClearValue(TagProperty);
                        functionMarker.ClearValue(ToolTipProperty);
                    }
                }
                catch (Exception E)
                {
                    cLogManager.LogException(E);
                }
            }
        }

        private void RefreshSubtitleSection(DetailsPageDataHistoryColumnModel columnData)
        {
            RefreshSubtitleValues(columnData);
            RefreshSubtitleFunctionmarker(columnData);
        }

        #endregion

        #endregion

        public DetailsPageDataHistoryTitleColumn()
        {
            InitializeComponent();
        }

        #region Events

        private void UserControl_Initialized(object sender, EventArgs e)
        {
            SetStyles();
        }

        #region Vertical Collapse

        public void ToggleVerticalCollapse(bool isVisible)
        {
            (MainGrid.Parent as FrameworkElement).Visibility = isVisible ? Visibility.Visible : Visibility.Collapsed;
        }

        public static readonly RoutedEvent StatusBorderClickedEvent = EventManager.RegisterRoutedEvent("StatusBorderClickedEventHandler", RoutingStrategy.Bubble, typeof(RoutedEventHandler), typeof(DetailsPageDataHistoryTitleColumn));

        public event RoutedEventHandler StatusBorderClickedEventHandler
        {
            add { AddHandler(StatusBorderClickedEvent, value); }
            remove { RemoveHandler(StatusBorderClickedEvent, value); }
        }

        private void RaiseStatusBorderClickedEvent()
        {
            RoutedEventArgs newEventArgs = new RoutedEventArgs(StatusBorderClickedEvent);
            RaiseEvent(newEventArgs);
        }

        private void TitleRowBorder_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
        {
            if (!(e.Source is FunctionMarker))
                RaiseStatusBorderClickedEvent();
        }

        private void TitleRowBorder_TouchDown(object sender, TouchEventArgs e)
        {
            if (!(e.Source is FunctionMarker))
                RaiseStatusBorderClickedEvent();
        }

        #endregion

        #region MouseOverChangedEvent

        #region Enter

        public static readonly RoutedEvent MouseEnterTitleRowEvent = EventManager.RegisterRoutedEvent("MouseEnterTitleRowEventHandler", RoutingStrategy.Bubble, typeof(RoutedEventHandler), typeof(DetailsPageDataHistoryTitleColumn));

        public event RoutedEventHandler MouseEnterTitleRowEventHandler
        {
            add { AddHandler(MouseEnterTitleRowEvent, value); }
            remove { RemoveHandler(MouseEnterTitleRowEvent, value); }
        }

        private void RaiseMouseEnterTitleRowEvent()
        {
            RoutedEventArgs newEventArgs = new RoutedEventArgs(MouseEnterTitleRowEvent);
            RaiseEvent(newEventArgs);
        }

        private void TitleRowBorder_MouseEnter(object sender, MouseEventArgs e)
        {
            RaiseMouseEnterTitleRowEvent();
        }

        #endregion

        #region Leave

        public static readonly RoutedEvent MouseLeaveTitleRowEvent = EventManager.RegisterRoutedEvent("MouseLeaveTitleRowEventHandler", RoutingStrategy.Bubble, typeof(RoutedEventHandler), typeof(DetailsPageDataHistoryTitleColumn));

        public event RoutedEventHandler MouseLeaveTitleRowEventHandler
        {
            add { AddHandler(MouseLeaveTitleRowEvent, value); }
            remove { RemoveHandler(MouseLeaveTitleRowEvent, value); }
        }

        private void RaiseMouseLeaveTitleRowEvent()
        {
            RoutedEventArgs newEventArgs = new RoutedEventArgs(MouseLeaveTitleRowEvent);
            RaiseEvent(newEventArgs);
        }

        private void TitleRowBorder_MouseLeave(object sender, MouseEventArgs e)
        {
            RaiseMouseLeaveTitleRowEvent();
        }

        #endregion

        #endregion

        #endregion

        #region Style Definitions

        private Style titleColumnOverViewTitleStyle;
        private Style titleColumnMainTitleStyle;
        private Style titleColumnSubTitleStyle;

        private void SetStyles()
        {
            titleColumnOverViewTitleStyle = (Style)FindResource("DetailsPage.DataHistory.TitleColumn.OverviewTitle");
            titleColumnMainTitleStyle = (Style)FindResource("DetailsPage.DataHistory.TitleColumn.MainTitle");
            titleColumnSubTitleStyle = (Style)FindResource("DetailsPage.DataHistory.TitleColumn.SubTitle");
        }

        #endregion

    }
}
