using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media.Effects;

using FasdDesktopUi.Basics.Enums;
using FasdDesktopUi.Basics.Models;
using FasdDesktopUi.Pages.DetailsPage.Models;
using FasdDesktopUi.Pages.DetailsPage;
using FasdDesktopUi.Basics.UserControls.AdaptableIcon;
using C4IT.FASD.Base;
using C4IT.MultiLanguage;
using FasdDesktopUi.Basics;
using System.Reflection;
using C4IT.Logging;
using static C4IT.Logging.cLogManager;
using FasdDesktopUi.Pages.SettingsPage;
using FasdDesktopUi.Pages.DetailsPage.UserControls;
using F4SD_AdaptableIcon.Enums;

namespace FasdDesktopUi.Pages.SlimPage.UserControls
{
    public partial class SlimPageWidgetCollection : UserControl
    {
        #region Properties

        #region IsBlurred

        private static void IsBlurredChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            if (d is SlimPageWidgetCollection _me && e.NewValue is bool isBlurred)
                _me.ValueBorder.Child.Effect = isBlurred ? new BlurEffect() { Radius = 5, KernelType = KernelType.Gaussian } : null;
        }

        public static readonly DependencyProperty IsBlurredProperty =
            DependencyProperty.Register("IsBlurred", typeof(bool), typeof(SlimPageWidgetCollection), new PropertyMetadata(false, new PropertyChangedCallback(IsBlurredChangedCallback)));

        public bool IsBlurred
        {
            get { return (bool)GetValue(IsBlurredProperty); }
            set { SetValue(IsBlurredProperty, value); }
        }

        #endregion

        public bool HasDirectConnection
        {
            get { return (bool)GetValue(HasDirectConnectionProperty); }
            set { SetValue(HasDirectConnectionProperty, value); }
        }

        public static readonly DependencyProperty HasDirectConnectionProperty =
            DependencyProperty.Register("HasDirectConnection", typeof(bool), typeof(SlimPageWidgetCollection), new PropertyMetadata(false, new PropertyChangedCallback(DirectConnectionStatusChanged)));

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

            _me.UpdateDirectConnectionIcon();
        }

        #region HeadingData DependencyProperty
        private static void HeadingDataChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            if (!(d is SlimPageWidgetCollection _me))
                return;

            if (!(e.NewValue is List<cHeadingDataModel> data))
                return;

            _me.UserStack.Children.RemoveRange(1, int.MaxValue);
            _me.ComputerStack.Children.RemoveRange(1, int.MaxValue);

            data = data.Where(heading =>
                heading.InformationClass is enumFasdInformationClass.User || heading.InformationClass is enumFasdInformationClass.Computer)
                .ToList();

            for (int i = 0; i < 2; i++)
            {
                var currentData = data[i];

                StackPanel stackPanel = null;
                AdaptableIcon icon = null;

                switch (currentData.InformationClass)
                {
                    case enumFasdInformationClass.Computer:
                        stackPanel = _me.ComputerStack;
                        icon = _me.ComputerIcon;
                        break;
                    case enumFasdInformationClass.User:
                        stackPanel = _me.UserStack;
                        icon = _me.UserIcon;
                        break;
                    default:
                        return;
                }

                if (currentData.IsOnline)
                {
                    icon.SetResourceReference(AdaptableIcon.PrimaryIconColorProperty, "Color.Green");
                    icon.ToolTip = cMultiLanguageSupport.GetItem("Header.IsOnline");
                }
                else
                {
                    icon.ClearValue(AdaptableIcon.PrimaryIconColorProperty);
                    icon.ToolTip = cMultiLanguageSupport.GetItem("Header.IsOffline");
                }

                TextBlock textBlock = new TextBlock();
                textBlock.SetResourceReference(StyleProperty, "SlimPage.Widget.Header");
                textBlock.Text = currentData.HeadingText;
                textBlock.MouseLeftButtonUp += _me.Heading_MouseLeftButtonUp;
                textBlock.TouchDown += _me.Heading_TouchDown;

                stackPanel.Children.Add(textBlock);

            }
        }

        private void Heading_Click(object originalSource) //todo: bring in separate function? same procedure in widget values and in DetailsPage
        {
            try
            {
                if (!(originalSource is TextBlock clickedTextBlock))
                    return;

                System.Windows.Forms.Clipboard.SetText(clickedTextBlock.Text);
            }
            catch { }
        }

        private void Heading_TouchDown(object sender, System.Windows.Input.TouchEventArgs e)
        {
            Heading_Click(e.OriginalSource);
        }

        private void Heading_MouseLeftButtonUp(object sender, System.Windows.Input.MouseButtonEventArgs e)
        {
            Heading_Click(e.OriginalSource);
        }

        public static readonly DependencyProperty HeadingDataProperty =
            DependencyProperty.Register("HeadingData", typeof(List<cHeadingDataModel>), typeof(SlimPageWidgetCollection), new PropertyMetadata(new List<cHeadingDataModel>()             {
                new cHeadingDataModel() { HeadingText = "UserName", InformationClass = enumFasdInformationClass.User },
                new cHeadingDataModel() { HeadingText = "ComputerName", InformationClass = enumFasdInformationClass.Computer }
            }, new PropertyChangedCallback(HeadingDataChanged)));


        public List<cHeadingDataModel> HeadingData
        {
            get { return (List<cHeadingDataModel>)GetValue(HeadingDataProperty); }
            set { SetValue(HeadingDataProperty, value); }
        }

        #endregion

        #region WidgetData DependencyProperty 

        private static void WidgetDataChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            if (d is SlimPageWidgetCollection _me)
                _me.InitializeWidgetData();
        }

        public static readonly DependencyProperty WidgetDataProperty =
            DependencyProperty.Register("WidgetData", typeof(List<List<cWidgetValueModel>>), typeof(SlimPageWidgetCollection), new PropertyMetadata(new List<List<cWidgetValueModel>>(), new PropertyChangedCallback(WidgetDataChangedCallback)));

        public List<List<cWidgetValueModel>> WidgetData
        {
            get { return (List<List<cWidgetValueModel>>)GetValue(WidgetDataProperty); }
            set { SetValue(WidgetDataProperty, value); }
        }

        #endregion

        #endregion

        public SlimPageWidgetCollection()
        {
            InitializeComponent();
        }

        #region InitializeWidgetData

        private void InitializeWidgetData()
        {
            try
            {

                if (WidgetData == null)
                    return;

                for (int i = 0; i < 2; i++)
                {
                    if (WidgetGrid.Children.Count <= i)
                        continue;

                    if (WidgetGrid.Children[i] is Panel widgetPanel)
                    {
                        widgetPanel.Children.Clear();
                        WidgetGrid.ColumnDefinitions[i].Width = new GridLength(1, GridUnitType.Auto);

                        if (WidgetData.Count <= i)
                            continue;

                        WidgetGrid.ColumnDefinitions[i].Width = new GridLength(1, GridUnitType.Star);

                        foreach (var widgetValue in WidgetData[i].OrderBy(x => x.ValueIndex))
                        {
                            if (string.IsNullOrEmpty(widgetValue.Title))
                            {
                                Border noTitleValueBorder = new Border() { ClipToBounds = true };
                                var noTitleValueTextBlock = new TextBlock() { Text = widgetValue.Value, Style = widgetNoTitleValueStyle };
                                noTitleValueTextBlock.MouseEnter += WidgetValue_MouseEnter;
                                noTitleValueTextBlock.MouseLeave += WidgetValue_MouseLeave;

                                noTitleValueBorder.Child = noTitleValueTextBlock;

                                widgetPanel.Children.Add(noTitleValueBorder);
                            }
                            else
                            {
                                //todo: add ticker text animation to values with title
                                StackPanel valueStackPanel = new StackPanel() { Orientation = Orientation.Horizontal };
                                valueStackPanel.Children.Add(new TextBlock() { Text = String.Format("{0}: ", widgetValue.Title), Style = widgetTitleStyle });

                                TextBlock valueTextBlock = new TextBlock() { Text = widgetValue.Value, Style = widgetValueStyle };

                                switch (widgetValue.HighlightIn)
                                {
                                    case enumHighlightColor.none:
                                        break;
                                    case enumHighlightColor.blue:
                                        valueTextBlock.SetResourceReference(ForegroundProperty, "Color.Blue");
                                        break;
                                    case enumHighlightColor.green:
                                        valueTextBlock.SetResourceReference(ForegroundProperty, "Color.Green");
                                        break;
                                    case enumHighlightColor.orange:
                                        valueTextBlock.SetResourceReference(ForegroundProperty, "Color.Orange");
                                        break;
                                    case enumHighlightColor.red:
                                        valueTextBlock.SetResourceReference(ForegroundProperty, "Color.Red");
                                        break;
                                    default:
                                        break;
                                }

                                valueStackPanel.Children.Add(valueTextBlock);
                                widgetPanel.Children.Add(valueStackPanel);
                            }
                        }
                    }
                }
            }
            catch (Exception E)
            {
                LogException(E);
            }
            finally
            {
            }
        }
        private void WidgetValue_MouseEnter(object sender, MouseEventArgs e)
        {
            try
            {
                if (!(sender is FrameworkElement senderElement))
                    return;

                if (!(senderElement.Parent is FrameworkElement senderParent))
                    return;

                cUtility.SetTickerTextAnimation(senderElement, senderParent);
            }
            catch (Exception E)
            {
                LogException(E);
            }

        }

        private void WidgetValue_MouseLeave(object sender, MouseEventArgs e)
        {
            try
            {
                if (!(sender is FrameworkElement senderElement))
                    return;

                senderElement.BeginAnimation(MarginProperty, null);
            }
            catch (Exception E)
            {
                LogException(E);
            }
        }


        #endregion

        private void UpdateDirectConnectionIcon()
        {
            try
            {
                if (HasDirectConnection)
                {
                    ComputerIcon.SelectedInternIcon = enumInternIcons.misc_directConnection;
                    ComputerIcon.BorderPadding = new Thickness(0);
                }
                else
                {
                    ComputerIcon.SelectedInternIcon = enumInternIcons.misc_computer;
                    ComputerIcon.ClearValue(AdaptableIcon.BorderPaddingProperty);
                }
            }
            catch (Exception E)
            {
                LogException(E);
            }
        }

        #region Styles

        private Style widgetNoTitleValueStyle;
        private Style widgetTitleStyle;
        private Style widgetValueStyle;

        private void SetStyles()
        {
            widgetNoTitleValueStyle = (Style)FindResource("SlimPage.Widget.NoTitleValue");
            widgetTitleStyle = (Style)FindResource("SlimPage.Widget.Title");
            widgetValueStyle = (Style)FindResource("SlimPage.Widget.Value");
        }

        #endregion

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

        private void WidgetCollection_Loaded(object sender, RoutedEventArgs e)
        {
            InitializeWidgetData();
        }

        #region WidgetCollection_Click

        private void WidgetCollection_Click(object originalSource)
        {
            try
            {
                if (originalSource is TextBlock clickedTextBlock)
                {
                    System.Windows.Forms.Clipboard.SetText(clickedTextBlock.Text);
                    return;
                }
                else if (originalSource == ValueBorder)
                {
                    var detailsPage = cSupportCaseDataProvider.detailsPage;
                    if (detailsPage != null)
                    {
                        Window.GetWindow(this).Hide();
                        App.HideAllSettingViews();
                        detailsPage.Show();
                    }
                }

            }
            catch { }
        }

        private void WidgetCollection_MouseUp(object sender, MouseButtonEventArgs e)
        {
            WidgetCollection_Click(e.OriginalSource);
        }

        private void WidgetCollection_TouchDown(object sender, TouchEventArgs e)
        {
            WidgetCollection_Click(e.OriginalSource);
        }

        #endregion

    }
}
