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
{
    [Obsolete("Instead use " + nameof(DynamicChart))]
    public partial class DetailedChart : UserControl
    {
        #region Variables
        static bool wasRendered = false;
        int DataDurationStart = 0;
        int DataDurationEnd = 0;
        int DataDurationTotal = 0;
        int ReducedTimeStamps = 0;
        DateTime firstTime;
        #endregion

        #region Dependency Properties

        #region ChartData

        public cDetailedChartModel ChartData
        {
            get { return (cDetailedChartModel)GetValue(ChartDataProperty); }
            set { SetValue(ChartDataProperty, value); }
        }

        public static readonly DependencyProperty ChartDataProperty =
            DependencyProperty.Register("ChartData", typeof(cDetailedChartModel), typeof(DetailedChart), new PropertyMetadata(null, new PropertyChangedCallback(HandleDependancyPropertyChanged)));


        private static void HandleDependancyPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            if (!(d is DetailedChart me)) return;
            me.BindingValueChange();
        }

        #endregion

        #region IsCloseButtonVisible

        public static readonly DependencyProperty IsCloseButtonVisibleProperty =
            DependencyProperty.Register("IsCloseButtonVisible", typeof(bool), typeof(DetailedChart), new PropertyMetadata(false));

        public bool IsCloseButtonVisible
        {
            get { return (bool)GetValue(IsCloseButtonVisibleProperty); }
            set { SetValue(IsCloseButtonVisibleProperty, value); }
        }

        #endregion

        #endregion

        public Action CloseButtonClickedAction { get; set; }

        [Obsolete("Instead use " + nameof(DynamicChart))]
        public DetailedChart()
        {
            InitializeComponent();
        }

        #region Binding

        public void BindingValueChange()
        {

            try
            {
                if (ChartData?.Data == null || ChartData.Data.Count <= 0) return;
                GraphicCanvas.Children.Clear();
                TimeStampGrid.Children.Clear();
                TimeStampGrid.ColumnDefinitions.Clear();
                GraphicDataProperty.Clear();
                ReducedTimeStamps = 0;
                FillGraphicDataProperty();
                FillVariables();
                CreateDateTitle();
                SetCanvasBorderPadding();
                CreateTimeStamps();
                DrawGraphicData();

                if (!wasRendered)
                {
                    wasRendered = true;
                    var _h = Dispatcher.Invoke(async () =>
                    {
                        await Task.Delay(50);
                        BindingValueChange();
                    });
                }
            }
            catch (Exception E)
            {
                LogException(E);
            }

        }

        #endregion

        #region GraphicDataProperty

        public List<cChartValue> GraphicDataProperty { get; set; } = new List<cChartValue>();

        public void FillGraphicDataProperty()
        {

            try
            {
                if (ChartData?.Data == null) return;
                var reverseData = ChartData.Data.ToList();
                reverseData.Reverse();

                if ((DateTime)reverseData[0][ChartData.TimeIndex] < (DateTime)reverseData[reverseData.Count() - 1][ChartData.TimeIndex])
                {
                    foreach (var item in reverseData)
                    {
                        cChartValue data = new cChartValue();
                        data.Value = (double)item[ChartData.ValueIndex];
                        data.Duration = int.Parse(item[ChartData.DurationIndex].ToString());
                        data.Time = (DateTime)item[ChartData.TimeIndex];
                        data.Time = data.Time.ToLocalTime();
                        GraphicDataProperty.Add(data);
                    }
                }
                else if ((DateTime)ChartData.Data[0][ChartData.TimeIndex] < (DateTime)ChartData.Data[ChartData.Data.Count() - 1][ChartData.TimeIndex] || ChartData.Data.Count == 1)
                {
                    foreach (var item in ChartData.Data)
                    {
                        cChartValue data = new cChartValue();
                        data.Value = (double)item[ChartData.ValueIndex];
                        data.Duration = int.Parse(item[ChartData.DurationIndex].ToString());
                        data.Time = (DateTime)item[ChartData.TimeIndex];
                        data.Time = data.Time.ToLocalTime();
                        GraphicDataProperty.Add(data);
                    }
                }
            }
            catch (Exception E)
            {
                LogException(E);
            }

        }

        #endregion

        #region FillVariables

        public void FillVariables()
        {

            try
            {
                firstTime = GraphicDataProperty.First<cChartValue>().Time;
                DateTime lastTime = GraphicDataProperty.Last<cChartValue>().Time;
                int lastDuration = GraphicDataProperty.Last<cChartValue>().Duration;

                lastTime = lastTime.AddMilliseconds(lastDuration);

                DataDurationStart = firstTime.Hour;
                if (lastTime.Minute != 0)
                {
                    lastTime = lastTime.AddMinutes(60 - (lastDuration / 60000));
                }
                DataDurationEnd = lastTime.Hour;
                DataDurationTotal = DataDurationEnd - DataDurationStart;
                if (firstTime.Date < lastTime.Date)
                {
                    if (DataDurationTotal < 2)
                    {
                        DataDurationTotal = (24 - DataDurationStart) + DataDurationEnd;
                    }
                }
                if (DataDurationTotal > 18)
                {
                    ReducedTimeStamps = 3;
                    if (DataDurationTotal % 4 == 3)
                    {
                        DataDurationTotal += 3;
                    }
                    else if (DataDurationTotal % 4 == 2)
                    {
                        DataDurationTotal += 2;
                    }
                    else if (DataDurationTotal % 4 == 1)
                    {
                        DataDurationTotal += 1;
                    }
                }
                else if (DataDurationTotal > 12)
                {
                    ReducedTimeStamps = 2;
                    if (DataDurationTotal % 3 == 2)
                    {
                        DataDurationTotal += 2;
                    }
                    else if (DataDurationTotal % 3 == 1)
                    {
                        DataDurationTotal += 1;
                    }
                }
                else if (DataDurationTotal > 6)
                {
                    ReducedTimeStamps = 1;
                    if (DataDurationTotal % 2 == 1)
                    {
                        DataDurationTotal += 1;
                    }
                }

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

        }

        #endregion

        #region Create Date Title

        public void CreateDateTitle()
        {

            try
            {
                DateTime dataDate = GraphicDataProperty.First<cChartValue>().Time;
                dataDate = dataDate.Date;
                DateBlock.Text = dataDate.ToString("dddd, dd.MM.yyyy");
                TitleBlock.Text = ChartData.ChartTitle;
            }
            catch (Exception E)
            {
                LogException(E);
            }

        }

        #endregion

        #region SetCanvasBorderPadding

        public void SetCanvasBorderPadding()
        {

            try
            {
                double borderWidth = GraphicBorder.ActualWidth;
                double paddingWidth = borderWidth / (((double)DataDurationTotal + 1) * 2.0);
                double borderHeight = GraphicBorder.ActualHeight;
                double paddingHeight = borderHeight / 10.0;
                paddingHeight = Math.Max(0, paddingHeight);
                paddingWidth = Math.Max(0, paddingWidth);
                GraphicBorder.Padding = new Thickness(paddingWidth, paddingHeight, paddingWidth, paddingHeight);
                GraphicBorder.UpdateLayout();
                CanvasBorder.UpdateLayout();
            }
            catch (Exception E)
            {
                LogException(E);
            }


        }

        #endregion

        #region Time Stamps

        public void CreateTimeStamps()
        {

            try
            {
                for (int i = 0; i <= DataDurationTotal; i++)
                {
                    ColumnDefinition timeStamp = new ColumnDefinition();
                    timeStamp.Width = new GridLength(1, GridUnitType.Star);
                    TimeStampGrid.ColumnDefinitions.Add(timeStamp);
                    if (ReducedTimeStamps == 3 && i % 4 != 0)
                    {
                        continue;
                    }
                    if (ReducedTimeStamps == 2 && i % 3 != 0)
                    {
                        continue;
                    }
                    if (ReducedTimeStamps == 1 && i % 2 != 0)
                    {
                        continue;
                    }
                    TextBlock TimeStampText = new TextBlock()
                    {
                        Text = (firstTime.AddHours(i)).Hour.ToString() + ":00",
                        FontFamily = new FontFamily("Calibri"),
                        FontSize = 11,
                        HorizontalAlignment = HorizontalAlignment.Center,
                        VerticalAlignment = VerticalAlignment.Center,
                        TextAlignment = TextAlignment.Center,
                        TextTrimming = TextTrimming.None,
                    };

                    TimeStampText.SetResourceReference(TextBlock.ForegroundProperty, "Color.Menu.Icon");

                    if (DataDurationTotal > 10)
                    {
                        TimeStampText.Margin = new Thickness(-7, 0, -7, 0);
                    }
                    Grid.SetColumn(TimeStampText, i);
                    TimeStampGrid.Children.Add(TimeStampText);
                }
            }
            catch (Exception E)
            {
                LogException(E);
            }

        }

        #endregion

        #region Draw Data

        public double CalculateSetLeft(DateTime dataTime)
        {
            double setLeft = (double)dataTime.Hour + ((double)dataTime.Minute / 60.0);
            setLeft = (setLeft - (double)DataDurationStart) * ((double)CanvasBorder.ActualWidth / ((double)DataDurationTotal));
            return setLeft;
        }

        public void DrawGraphicData()
        {

            try
            {
                double setLeft = 0.0;
                double setFactor = 0.0;

                setFactor = (GraphicCanvas.ActualHeight - 8.0) / 100.0;

                foreach (var data in GraphicDataProperty)
                {

                    DateTime dataTime = data.Time;
                    double dataValue = data.Value;
                    int dataDuration = data.Duration;

                    Border border = new Border
                    {
                        Height = 8.0,
                        Width = (double)dataDuration * ((double)CanvasBorder.ActualWidth / ((double)DataDurationTotal)) / 3600000.0,
                        CornerRadius = new CornerRadius(4.0),
                        ToolTip = dataTime.ToShortTimeString() + " - " + dataTime.AddMilliseconds(dataDuration).ToShortTimeString() + " | " + (int)dataValue + "%"
                    };
                    if (border.Width < 8)
                    {
                        border.Width = 8;
                    }
                    if (ChartData.IsThresholdActive == false)
                    {
                        border.Background = new SolidColorBrush(Color.FromRgb(0, 157, 221));
                    }
                    else if (dataValue >= ChartData.ErrorThreshold)
                    {
                        border.Background = new SolidColorBrush(Color.FromRgb(206, 61, 54));
                    }
                    else if (dataValue >= ChartData.WarningThreshold)
                    {
                        border.Background = new SolidColorBrush(Color.FromRgb(251, 157, 40));
                    }
                    else
                    {
                        border.Background = new SolidColorBrush(Color.FromRgb(117, 177, 89));
                    }
                    setLeft = CalculateSetLeft(dataTime);
                    Canvas.SetBottom(border, dataValue * setFactor);
                    Canvas.SetLeft(border, setLeft);
                    GraphicCanvas.Children.Add(border);

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

        }

        #endregion

        #region Close Button

        private void CloseButton_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
        {
            CloseButton_Click();
        }

        private void CloseButton_TouchDown(object sender, TouchEventArgs e)
        {
            CloseButton_Click();
        }
        private void CloseButton_Click()
        {
            CloseButtonClickedAction?.Invoke();
        }

        #endregion

        public class cChartValue
        {
            public DateTime Time { get; set; }
            public double Value { get; set; }
            public int Duration { get; set; }

        }
    }
}
