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.Logging;
using C4IT.FASD.Base;
using FasdDesktopUi.Basics;
using FasdDesktopUi.Basics.Models;
using FasdDesktopUi.Basics.UserControls;
using FasdDesktopUi.Basics.UserControls.AdaptableIcon;
using FasdDesktopUi.Pages.DetailsPage.Models;
using static C4IT.Logging.cLogManager;
using F4SD_AdaptableIcon.Enums;

namespace FasdDesktopUi.Pages.DetailsPage.UserControls
{

    public partial class DetailsPageDataHistorySection : UserControl
    {

        #region Properties

        #region Geometry

        private static bool DidGeometryDataChange(DependencyPropertyChangedEventArgs e)
        {
            bool didGeometryChange = false;

            try
            {
                if (e.NewValue != null && e.OldValue != null)
                {
                    var newValue = (int)e.NewValue;
                    var oldValue = (int)e.OldValue;

                    didGeometryChange = newValue != oldValue || didGeometryChange;
                }
                else
                {
                    didGeometryChange = true;
                }
            }
            catch (Exception E)
            {
                LogException(E);
            }

            return didGeometryChange;
        }

        private static void GeometryChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            if (DidGeometryDataChange(e) is false)
                return;

            if (!(d is DetailsPageDataHistorySection _me))
                return;

            _me.ClearControls();
            _me.TitleColumnUc.Tag = _me;
            _me.TitleColumnUc.SubtitleCount = _me.SubtitleCount;
            _me.InitializeValueColumns();
        }

        #region SubtitleCount DependencyProperty

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

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

        #endregion

        #region ColoumnCount DependencyProperty

        public static readonly DependencyProperty ColumnCountProperty =
            DependencyProperty.Register("ColumnCount", typeof(int), typeof(DetailsPageDataHistorySection), new PropertyMetadata(1));

        public int ColumnCount
        {
            get { return (int)GetValue(ColumnCountProperty); }
            set { SetValue(ColumnCountProperty, value); }
        }

        #endregion

        #endregion

        #region HistoryData DependencyProperty

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

            if (_me.HistoryData == null)
            {
                foreach (DetailsPageDataHistoryValueColumn valueColumn in _me.MainGrid.Children)
                {
                    valueColumn.ColumnValues = new DetailsPageDataHistoryColumnModel() { HighlightColor = Basics.Enums.enumHighlightColor.none, IsLoading = true, ColumnValues = new List<cDataHistoryValueModel>() { new cDataHistoryValueModel() { Content = "-", IsLoading = true } } };
                }
                return;
            }

            _me.TitleColumnUc.ColumnValues = _me.HistoryData.TitleColumn;
            _me.RefreshValueColumnValues();
        }

        public static readonly DependencyProperty HistoryDataProperty =
            DependencyProperty.Register("HistoryData", typeof(cDetailsPageDataHistoryCategoryDataModel), typeof(DetailsPageDataHistorySection), new PropertyMetadata(new cDetailsPageDataHistoryCategoryDataModel(), new PropertyChangedCallback(RefreshDataCallback)));

        public cDetailsPageDataHistoryCategoryDataModel HistoryData
        {
            get { return (cDetailsPageDataHistoryCategoryDataModel)GetValue(HistoryDataProperty); }
            set { SetValue(HistoryDataProperty, value); }
        }

        #endregion

        #region TitleRowIsHighlighted DependencyProperty

        public static readonly DependencyProperty TitleRowIsHighlightedProperty =
            DependencyProperty.Register("TitleRowIsHighlighted", typeof(bool), typeof(DetailsPageDataHistorySection), new PropertyMetadata(false));

        public bool TitleRowIsHighlighted
        {
            get { return (bool)GetValue(TitleRowIsHighlightedProperty); }
            set { SetValue(TitleRowIsHighlightedProperty, value); }
        }

        #endregion

        #region IsVerticalExpanded

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

            if (!(e.NewValue is bool isVisible))
                return;

            _me.TitleColumnUc.ToggleVerticalCollapse(isVisible);

            if (isVisible)
                _me.TitleColumnUc.ClearValue(HeightProperty);
            else
                _me.TitleColumnUc.Height = 60;

            _me.TitleRowEndBorder.CornerRadius = isVisible ? new CornerRadius(0, 7.5, 0, 0) : new CornerRadius(0, 7.5, 7.5, 0);
            _me.TitleColumnUc.TitleRowBorder.CornerRadius = isVisible ? new CornerRadius(7.5, 0, 0, 0) : new CornerRadius(7.5, 0, 0, 7.5);
            _me.TitleRowIsHighlighted = isVisible;

            for (int i = 0; i < _me.MainGrid.Children.Count; i++)
            {
                if (_me.MainGrid.Children[i] is DetailsPageDataHistoryValueColumn valueColumn)
                    valueColumn.ToggleVerticalCollapse(isVisible);
            }
        }

        public static readonly DependencyProperty IsVerticalExpandedProperty =
            DependencyProperty.Register("IsVerticalExpanded", typeof(bool), typeof(DetailsPageDataHistorySection), new PropertyMetadata(false, new PropertyChangedCallback(IsVerticalExpandedChangedCallback)));

        public bool IsVerticalExpanded
        {
            get { return (bool)GetValue(IsVerticalExpandedProperty); }
            set { SetValue(IsVerticalExpandedProperty, value); }
        }

        #endregion

        #region IsVerticalExpandLocked

        public static readonly DependencyProperty IsVerticalExpandLockedProperty =
            DependencyProperty.Register("IsVerticalExpandLocked", typeof(bool), typeof(DetailsPageDataHistorySection), new PropertyMetadata(false));

        public bool IsVerticalExpandLocked
        {
            get { return (bool)GetValue(IsVerticalExpandLockedProperty); }
            set { SetValue(IsVerticalExpandLockedProperty, value); }
        }

        #endregion

        #region IsHorizontalCollapsed

        public static readonly DependencyProperty IsHorizontalCollapsedProperty =
            DependencyProperty.Register("IsHorizontalCollapsed", typeof(bool), typeof(DetailsPageDataHistorySection), new PropertyMetadata(true));

        public bool IsHorizontalCollapsed
        {
            get { return (bool)GetValue(IsHorizontalCollapsedProperty); }
            set { SetValue(IsHorizontalCollapsedProperty, value); }
        }

        #endregion

        public int ShownValueColumnsCount { get; set; } = 7;

        private List<int> aggregateRowIndexes = new List<int>();

        #endregion

        #region Controls

        private readonly List<DetailsPageDataHistoryValueColumn> ValueColumns = new List<DetailsPageDataHistoryValueColumn>();

        #endregion

        private void ClearControls()
        {
            if (MainGrid.ColumnDefinitions.Count <= 1)
                return;

            ValueColumns.ForEach(valueColumn => MainGrid.Children.Remove(valueColumn));
            MainGrid.ColumnDefinitions.RemoveRange(1, MainGrid.RowDefinitions.Count - 1);
            ValueColumns.Clear();
        }

        #region InitalizeControls

        private void InitializeSingleValueColumn(int columnIndex)
        {
            MainGrid.ColumnDefinitions.Add(new ColumnDefinition());

            var valueColumn = new DetailsPageDataHistoryValueColumn() { SubtitleCount = this.SubtitleCount, MinWidth = HistoryData.ValueColumnWidth, ColumnWidth = HistoryData.ValueColumnWidth, Margin = new Thickness(-0.25, 0, -0.25, 0), Tag = this };
            valueColumn.MouseEnterTitleRowEventHandler += MouseEnterTitleRow;
            valueColumn.MouseLeaveTitleRowEventHandler += MouseLeaveTitleRow;
            Grid.SetColumn(valueColumn, columnIndex);

            MainGrid.Children.Add(valueColumn);
            ValueColumns.Add(valueColumn);
        }

        private void InitializeValueColumns()
        {
            for (int i = 0; i <= ColumnCount; i++)
            {
                try
                {
                    InitializeSingleValueColumn(i);
                }
                catch (Exception E)
                {
                    LogException(E);
                }
            }
        }

        #endregion

        private void RefreshValueColumnValues()
        {
            try
            {
                var valueColumnEnumerator = HistoryData.ValueColumns.GetEnumerator();

                //MainGrid.ColumnDefinitions[0].Width = new GridLength(HistoryData.ValueColumnWidth);

                foreach (var valueColumnControl in ValueColumns)
                {
                    try
                    {
                        if (!valueColumnEnumerator.MoveNext())
                        {
                            valueColumnControl.Visibility = Visibility.Collapsed;
                            continue;
                        }

                        valueColumnControl.Width = HistoryData.ValueColumnWidth;
                        valueColumnControl.Visibility = Visibility.Visible;
                        var titleColumnEnumerator = HistoryData.TitleColumn.ColumnValues.GetEnumerator();

                        aggregateRowIndexes = Enumerable.Range(0, HistoryData.TitleColumn.ColumnValues.Count)
                                                        .Where(subtitleIndex => HistoryData.TitleColumn.ColumnValues[subtitleIndex].PresentationStyle == Basics.Enums.enumHistoryTitleType.aggregate)
                                                        .ToList();
                        valueColumnControl.AggregateRowIndexes = aggregateRowIndexes;

                        valueColumnControl.ColumnValues = valueColumnEnumerator.Current;
                    }
                    catch (Exception E)
                    {
                        LogException(E);
                    }
                }
            }
            catch (Exception E)
            {
                LogException(E);
            }
        }

        private bool DidColumnDataChange(DetailsPageDataHistoryColumnModel oldData, DetailsPageDataHistoryColumnModel newData)
        {
            try
            {
                if (oldData?.ColumnValues?.Count != newData?.ColumnValues?.Count)
                    return true;

                for (int i = 0; i < newData.ColumnValues.Count; i++)
                {
                    var oldCellValue = oldData.ColumnValues[i];
                    var newCellValue = newData.ColumnValues[i];

                    if (oldCellValue.Content.Equals(newCellValue.Content) == false || oldCellValue.IsLoading != newCellValue.IsLoading)
                        return true;
                }

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

            return false;
        }

        public void UpdateHistoryData(cDetailsPageDataHistoryCategoryDataModel historyData)
        {
            var CM = MethodBase.GetCurrentMethod();
            LogMethodBegin(CM);
            try
            {
                if (historyData is null)
                    return;

                for (int i = 0; i < historyData.ValueColumns.Count; i++)
                {
                    var oldColumnValues = HistoryData?.ValueColumns.Count > i ? HistoryData?.ValueColumns[i] : null;
                    var newColumnValues = historyData.ValueColumns[i];

                    if (DidColumnDataChange(oldColumnValues, newColumnValues))
                        ValueColumns[i]?.UpdateHistoryValues(newColumnValues);
                }
            }
            catch (Exception E)
            {
                LogException(E);
            }
            finally
            {
                LogMethodEnd(CM);
            }
        }

        public DetailsPageDataHistorySection()
        {
            InitializeComponent();
        }

        #region Events

        #region Horizontal Collapse

        public static readonly RoutedEvent HorizontalCollapseClickedEvent = EventManager.RegisterRoutedEvent("HorizontalCollapseClickedEventHandler", RoutingStrategy.Bubble, typeof(RoutedEventHandler), typeof(DetailsPageDataHistorySection));

        public event RoutedEventHandler HorizontalCollapseClickedEventHandler
        {
            add { AddHandler(HorizontalCollapseClickedEvent, value); }
            remove { RemoveHandler(HorizontalCollapseClickedEvent, value); }
        }

        private void RaiseHorizontalCollapseClickedEvent()
        {
            RoutedEventArgs newEventArgs = new RoutedEventArgs(HorizontalCollapseClickedEvent);
            RaiseEvent(newEventArgs);
        }

        private void HorizontalCollapse_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
        {
            RaiseHorizontalCollapseClickedEvent();
        }

        private void HorizontalCollapse_TouchDown(object sender, TouchEventArgs e)
        {
            RaiseHorizontalCollapseClickedEvent();
        }

        #endregion

        #endregion

        private void HistoryValueScrollViewer_PreviewMouseWheel(object sender, MouseWheelEventArgs e)
        {
            if (sender is ScrollViewer && !e.Handled)
            {
                e.Handled = true;
                var eventArg = new MouseWheelEventArgs(e.MouseDevice, e.Timestamp, e.Delta)
                {
                    RoutedEvent = MouseWheelEvent,
                    Source = sender
                };
                var parent = ((Control)sender).Parent as UIElement;
                parent.RaiseEvent(eventArg);
            }
        }

        #region LockIcon Events

        private void LockIcon_Click(object sender)
        {
            try
            {
                if (sender is AdaptableIcon senderIcon)
                {
                    if (IsVerticalExpandLocked)
                    {
                        senderIcon.SetResourceReference(AdaptableIcon.PrimaryIconColorProperty, "Color.SoftContrast");
                        senderIcon.SelectedInternIcon = enumInternIcons.lock_open;
                    }
                    else
                    {
                        senderIcon.SetResourceReference(AdaptableIcon.PrimaryIconColorProperty, "Color.Menu.Icon");
                        senderIcon.SelectedInternIcon = enumInternIcons.lock_closed;
                    }

                    senderIcon.BorderPadding = new Thickness(5.5);
                }

                IsVerticalExpandLocked = !IsVerticalExpandLocked;
            }
            catch (Exception E)
            {
                LogException(E);
            }
        }

        private void LockIcon_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
        {
            LockIcon_Click(sender);
        }

        private void LockIcon_TouchDown(object sender, TouchEventArgs e)
        {
            LockIcon_Click(sender);
        }

        private void LockIcon_MouseLeave(object sender, MouseEventArgs e)
        {
            (sender as AdaptableIcon).ClearValue(AdaptableIcon.PrimaryIconColorProperty);
            (sender as AdaptableIcon).ClearValue(AdaptableIcon.SelectedInternIconProperty);
            (sender as AdaptableIcon).ClearValue(AdaptableIcon.BorderPaddingProperty);
        }

        #endregion

        #region HighlightBorder Events

        private void SetTitleRowIsHighlighted(bool isHighlighted)
        {
            if (isHighlighted)
            {
                TitleRowIsHighlighted = isHighlighted;
                TitleColumnUc.TitleOverviewControl.SetResourceReference(ForegroundProperty, "Color.FunctionMarker");
            }
            else
            {
                TitleColumnUc.TitleOverviewControl.ClearValue(ForegroundProperty);
                if (!IsVerticalExpanded)
                {
                    TitleRowIsHighlighted = isHighlighted;
                }
            }
        }

        private void MouseEnterTitleRow(object sender, RoutedEventArgs e)
        {
            SetTitleRowIsHighlighted(true);
        }

        private void MouseLeaveTitleRow(object sender, RoutedEventArgs e)
        {
            SetTitleRowIsHighlighted(false);
        }

        private void TitleRowEndBorder_MouseEnter(object sender, MouseEventArgs e)
        {
            SetTitleRowIsHighlighted(true);
        }

        private void TitleRowEndBorder_MouseLeave(object sender, MouseEventArgs e)
        {
            SetTitleRowIsHighlighted(false);
        }

        #endregion
    }
}
