using C4IT.FASD.Base;
using C4IT.MultiLanguage;
using FasdCockpitBase.Models;
using FasdDesktopUi.Basics.UserControls;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using static C4IT.Logging.cLogManager;

namespace FasdDesktopUi.Basics.Models
{
    public class cDataCanvasDataModel
    {
        public cRecommendationDataModel RecommendationData { get; set; }

        public Func<Task<cDetailedDataModel>> GetDetailedDataAsync { get; set; }

        public Func<Task<cDetailedChartModel>> GetDatailedChartDataAsync { get; set; }

        public Func<Task<cChartModel>> GetChartDataAsync { get; set; }

        public cDetailedDataModel DetailedData { get; set; }

        public cDetailedChartModel DetailedChartData { get; set; }

        public cChartModel ChartData { get; set; }

        public cQuickActionStatusMonitorModel QuickActionStatusMonitorData { get; set; }
    }

    public class cRecommendationDataModel
    {
        public string Category { get; set; }
        public string Recommendation { get; set; }
    }

    public class cDetailedDataModel
    {
        public string Heading { get; set; }

        public bool HasColumnHeaders = true;

        public List<object> FullDetailedData { get; set; }
    }

    public class cDetailedChartModel
    {
        public List<object[]> Data { get; set; }
        public int TimeIndex { get; set; }
        public int ValueIndex { get; set; }
        public int DurationIndex { get; set; }
        public double WarningThreshold { get; set; }
        public double ErrorThreshold { get; set; }
        public bool IsThresholdActive { get; set; }
        public string ChartTitle { get; set; }
    }

    public class cChartModel
    {
        public List<object[]> Data { get; set; }
        public int TimeIndex { get; set; }
        public int ValueIndex { get; set; }
        public int DurationIndex { get; set; }
        public double WarningThreshold { get; set; }
        public double ErrorThreshold { get; set; }
        public bool IsThresholdActive { get; set; }
        public bool IsDirectionUp { get; set; }
        public string ChartTitle { get; set; }
        public int StepLengthScale { get; set; }
        public int StepLengthLine { get; set; }
        public int MaxValue { get; set; }
        public int MinValue { get; set; }
        public string UnitFormat { get; set; }
    }

    public class cQuickActionStatusMonitorModel
    {
        public class cQuickActionStep : INotifyPropertyChanged
        {
            public enum enumActionStepType
            {
                main,
                connectingToClient,
                waitingForUserAcceptance,
                running,
                finished
            }

            private enumQuickActionRevisionStatus status;
            public enumQuickActionRevisionStatus Status
            {
                get => status; set
                {
                    status = value;
                    PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(Status)));
                }
            }

            public string DisplayName { get; private set; }
            public string QuickActionName { get; private set; }
            public enumActionStepType StepType { get; private set; }
            public List<cQuickActionStep> SubSteps { get; set; }

            public event PropertyChangedEventHandler PropertyChanged;

            public cQuickActionStep(string displayName, string quickActionName, enumActionStepType stepType)
            {
                DisplayName = displayName;
                QuickActionName = quickActionName;
                StepType = stepType;
            }

            public static void SetQuickActionStepStatuses(List<cQuickActionStep> actionSteps, string quickActionName, enumActionStepType type, enumQuickActionRevisionStatus status = enumQuickActionRevisionStatus.finishedSuccessfull)
            {
                try
                {
                    foreach (var step in actionSteps)
                    {
                        if (step.StepType.Equals(type) && step.QuickActionName.Equals(quickActionName))
                            step.Status = status;

                        if (step.SubSteps?.Count > 0)
                            SetQuickActionStepStatuses(step.SubSteps, quickActionName, type, status);
                    }
                }
                catch (Exception E)
                {
                    LogException(E);
                }
            }

            public static void CancelRemainingQuickActionSteps(List<cQuickActionStep> actionSteps)
            {
                try
                {
                    if (actionSteps is null || actionSteps.Count <= 0)
                        return;

                    foreach (var step in actionSteps)
                    {
                        if (step.Status == enumQuickActionRevisionStatus.inProgress)
                            step.Status = enumQuickActionRevisionStatus.canceled;

                        CancelRemainingQuickActionSteps(step.SubSteps);
                    }
                }
                catch (Exception E)
                {
                    LogException(E);
                }
            }

            internal static void SetAllQuickActionStepStatuses(List<cQuickActionStep> actionSteps, enumQuickActionRevisionStatus status = enumQuickActionRevisionStatus.inProgress)
            {
                try
                {
                    foreach (var step in actionSteps)
                    {
                        step.Status = status;

                        if (step.SubSteps?.Count > 0)
                            SetAllQuickActionStepStatuses(step.SubSteps, status);
                    }
                }
                catch (Exception E)
                {
                    LogException(E);
                }
            }
        }

        public bool RequiresUserPermission { get; set; }

        public cFasdQuickAction QuickActionDefinition { get; set; }

        public string ActionName { get; set; }

        public List<cQuickActionStep> ActionSteps { get; set; }

        public Dictionary<string, cAdjustableParameter> QuickActionParameters { get; set; }

        public delegate Task<List<object>> RunQuickActionDelegate(CancellationToken token, Dictionary<cAdjustableParameter, object> ParameterDictionary = null);

        public RunQuickActionDelegate RunQuickAction { get; set; }
    }
}
