using C4IT.FASD.Base;
using C4IT.MultiLanguage;
using F4SD_AdaptableIcon;
using F4SD_AdaptableIcon.Enums;
using FasdDesktopUi.Basics.Converter;
using FasdDesktopUi.Basics.UiActions;
using System.ComponentModel;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using static FasdDesktopUi.Basics.UiActions.cUiQuickTipAction;

namespace FasdDesktopUi.Basics.UserControls.QuickTip
{
    public partial class QuickTipStep : UserControl, INotifyPropertyChanged
    {

        #region Events

        public event PropertyChangedEventHandler PropertyChanged;

        #region RequestFocus

        public static readonly RoutedEvent RequestFocusEvent = EventManager.RegisterRoutedEvent(
            name: nameof(RequestFocus),
            routingStrategy: RoutingStrategy.Bubble,
            handlerType: typeof(RoutedEventHandler),
            ownerType: typeof(QuickTipStep));

        public event RoutedEventHandler RequestFocus
        {
            add { AddHandler(RequestFocusEvent, value); }
            remove { RemoveHandler(RequestFocusEvent, value); }
        }

        #endregion

        #region SuccessStateChanged

        public static readonly RoutedEvent SuccessStateChangedEvent = EventManager.RegisterRoutedEvent(
            name: nameof(SuccessStateChanged),
            routingStrategy: RoutingStrategy.Bubble,
            handlerType: typeof(RoutedEventHandler),
            ownerType: typeof(QuickTipStep));

        public event RoutedEventHandler SuccessStateChanged
        {
            add { AddHandler(SuccessStateChangedEvent, value); }
            remove { RemoveHandler(SuccessStateChangedEvent, value); }
        }

        #endregion

        #endregion

        #region Properties

        #region StepData

        public cUiQuickTipElement StepData
        {
            get { return (cUiQuickTipElement)GetValue(StepDataProperty); }
            set { SetValue(StepDataProperty, value); }
        }

        public static readonly DependencyProperty StepDataProperty =
            DependencyProperty.Register("StepData", typeof(cUiQuickTipElement), typeof(QuickTipStep), new PropertyMetadata(null, HandleStepDataChanged));

        private static void HandleStepDataChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            if (!(d is QuickTipStep step))
                return;

            step.UpdateStepIcon();
            step.UpdateStepTypeIcon();
            step.UpdateRequiredIcon();
        }

        private void UpdateStepIcon()
        {
            if (StepData.ElementType == Enums.enumQuickTipElementType.Automated)
            {
                if (!(StepData.StepUiAction is cUiQuickAction quickAction))
                    return;

                StepIcon = IconDataConverter.Convert(quickAction.QuickActionConfig.Icon);
            }
            else if (StepData.ElementType == Enums.enumQuickTipElementType.Manual)
                StepIcon = StepData.Icon;

        }

        private void UpdateStepTypeIcon()
        {
            if (StepData.ElementType == Enums.enumQuickTipElementType.Automated)
            {
                StepTypeIconData = new IconData(enumInternIcons.misc_functionBolt);
                StepTypeIcon.ToolTip = cMultiLanguageSupport.GetItem("QuickTips.Steps.Automated");
            }
            else if (StepData.ElementType == Enums.enumQuickTipElementType.Manual)
            {
                StepTypeIconData = new IconData(enumInternIcons.misc_tool);
                StepTypeIcon.ToolTip = cMultiLanguageSupport.GetItem("QuickTips.Steps.Manual");
            }
        }

        private void UpdateRequiredIcon()
        {
            if (StepData.IsRequired && (SuccessState == enumQuickActionSuccess.error || SuccessState == enumQuickActionSuccess.unknown))
            {
                RequiredIcon.Visibility = Visibility.Visible;
                RequiredIcon.IsHitTestVisible = true;
            }
            else
            {
                RequiredIcon.Visibility = Visibility.Hidden;
                RequiredIcon.IsHitTestVisible = false;
            }
        }

        #endregion

        #region StepTypeIconData
        private IconData _stepTypeIconData;

        public IconData StepTypeIconData
        {
            get => _stepTypeIconData;
            set
            {
                _stepTypeIconData = value;
                PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(StepTypeIconData)));
            }
        }
        #endregion

        #region HasFocus

        public bool HasFocus
        {
            get { return (bool)GetValue(HasFocusProperty); }
            set { SetValue(HasFocusProperty, value); }
        }

        public static readonly DependencyProperty HasFocusProperty =
            DependencyProperty.Register("HasFocus", typeof(bool), typeof(QuickTipStep), new PropertyMetadata(false, HandleHasFocusChanged));

        private static void HandleHasFocusChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            if (d is QuickTipStep step)
            {
                step.UpdateFocusBorder();
                step.Cursor = step.HasFocus ? null : Cursors.Hand;
            }
        }

        private void RunStepUiAction()
        {
            if (!HasFocus)
                return;

            cUiActionBase.RaiseEvent(StepData.StepUiAction, this, this);
        }

        private void UpdateFocusBorder()
        {
            if (HasFocus)
            {
                if (StepData.ElementType == Enums.enumQuickTipElementType.Manual)
                    StatusControl.IsHitTestVisible = true;

                MainBorder.SetResourceReference(BorderBrushProperty, "Color.FunctionMarker");
            }
            else
            {
                StatusControl.IsHitTestVisible = false;
                MainBorder.SetResourceReference(BorderBrushProperty, "BackgroundColor.DetailsPage.DataHistory.TitleColumn");
            }
        }

        public void HighlightAsRequired() => MainBorder.SetResourceReference(BorderBrushProperty, "Color.Red");

        #endregion

        #region StepIcon

        public IconData StepIcon
        {
            get { return (IconData)GetValue(StepIconProperty); }
            set { SetValue(StepIconProperty, value); }
        }

        public static readonly DependencyProperty StepIconProperty =
            DependencyProperty.Register("StepIcon", typeof(IconData), typeof(QuickTipStep), new PropertyMetadata(new IconData(enumInternIcons.misc_dot)));

        #endregion

        #region SuccessState

        public enumQuickActionSuccess SuccessState
        {
            get { return (enumQuickActionSuccess)GetValue(SuccessStateProperty); }
            set { SetValue(SuccessStateProperty, value); }
        }

        public static readonly DependencyProperty SuccessStateProperty =
            DependencyProperty.Register("SuccessState", typeof(enumQuickActionSuccess), typeof(QuickTipStep), new PropertyMetadata(enumQuickActionSuccess.unknown, HandleSuccessStateChanged));

        private static void HandleSuccessStateChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            if (!(d is QuickTipStep step))
                return;

            step.UpdateStatusControl();
        }

        private void UpdateStatusControl()
        {
            ErrorIcon.SetResourceReference(AdaptableIcon.AdaptableIcon.PrimaryIconColorProperty, "Color.Menu.Icon");
            UnknownIcon.SetResourceReference(AdaptableIcon.AdaptableIcon.PrimaryIconColorProperty, "Color.Menu.Icon");
            FinishedIcon.SetResourceReference(AdaptableIcon.AdaptableIcon.PrimaryIconColorProperty, "Color.Menu.Icon");

            ErrorIcon.Opacity = 0.35;
            UnknownIcon.Opacity = 0.35;
            FinishedIcon.Opacity = 0.35;

            switch (SuccessState)
            {
                case enumQuickActionSuccess.error:
                    ErrorIcon.SetResourceReference(AdaptableIcon.AdaptableIcon.PrimaryIconColorProperty, "HighlightColor.Red");
                    ErrorIcon.Opacity = 1;
                    break;
                case enumQuickActionSuccess.unknown:
                    UnknownIcon.SetResourceReference(AdaptableIcon.AdaptableIcon.PrimaryIconColorProperty, "Color.Menu.Icon");
                    UnknownIcon.Opacity = 1;
                    break;
                case enumQuickActionSuccess.finished:
                case enumQuickActionSuccess.successfull:
                    FinishedIcon.SetResourceReference(AdaptableIcon.AdaptableIcon.PrimaryIconColorProperty, "HighlightColor.Green");
                    FinishedIcon.Opacity = 1;
                    break;
                default:
                    break;
            }

            UpdateStepCount();
            UpdateRequiredIcon();
        }

        #endregion

        #endregion

        public QuickTipStep()
        {
            InitializeComponent();
        }

        private void MainBorder_TouchDown(object sender, TouchEventArgs e)
        {
            SetFocusForStep();
            RunStepUiAction();
        }

        private void MainBorder_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
        {
            SetFocusForStep();
            RunStepUiAction();
        }

        private void SetFocusForStep()
        {
            if (HasFocus)
                return;

            RoutedEventArgs eventArgs = new RoutedEventArgs(routedEvent: RequestFocusEvent);

            RaiseEvent(eventArgs);
        }

        private void UpdateStepCount()
        {
            RoutedEventArgs eventArgs = new RoutedEventArgs(routedEvent: SuccessStateChangedEvent);
            RaiseEvent(eventArgs);
        }

        private void SelectStatus_TouchDown(object sender, TouchEventArgs e)
        {
            SetSuccessState(sender);
        }

        private void SelectStatus_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
        {
            SetSuccessState(sender);
        }

        private void SetSuccessState(object sender)
        {
            if (!(StepData.ElementType == Enums.enumQuickTipElementType.Manual))
                return;

            if (!(sender is FrameworkElement frameworkElement))
                return;

            switch (frameworkElement.Tag)
            {
                case "Error":
                    SuccessState = enumQuickActionSuccess.error;
                    break;
                case "Unknown":
                    SuccessState = enumQuickActionSuccess.unknown;
                    break;
                case "Finished":
                    SuccessState = enumQuickActionSuccess.finished;
                    break;
                default:
                    return;
            }
        }

        private void MainBorder_MouseEnter(object sender, MouseEventArgs e)
        {
            HeadingIcon.SetResourceReference(AdaptableIcon.AdaptableIcon.PrimaryIconColorProperty, "Color.Menu.Icon.Hover");
        }

        private void MainBorder_MouseLeave(object sender, MouseEventArgs e)
        {
            HeadingIcon.SetResourceReference(AdaptableIcon.AdaptableIcon.PrimaryIconColorProperty, "Color.Menu.Icon");
        }
    }
}
