using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

using FasdDesktopUi.Basics.Models;
using C4IT.FASD.Base;
using C4IT.MultiLanguage;
using static C4IT.Logging.cLogManager;
using C4IT.F4SD.DisplayFormatting;

namespace FasdDesktopUi.Basics.UiActions
{
    public class cUiChainQuickAction : cUiQuickAction
    {
        private readonly List<cFasdQuickAction> chainedQuickActionConfigs = new List<cFasdQuickAction>();

        public int QuickActionCount { get => chainedQuickActionConfigs?.Count ?? 0; }

        public cF4sdQuickActionChained ChainedQuickAction { get; set; }

        public cUiChainQuickAction(cF4sdQuickActionChained quickAction) : base(quickAction)
        {
            ChainedQuickAction = quickAction;

            foreach (var quickActionName in quickAction.QuickActionNames)
            {
                if ((cF4SDCockpitXmlConfig.Instance?.QuickActionConfig?.F4SDQuickActions.QuickActions.TryGetValue(quickActionName, out var chainedQuickAction) ?? false))
                    chainedQuickActionConfigs.Add(chainedQuickAction);
                else
                    LogEntry($"Couldn't find Quick Action with name '{quickActionName}'", C4IT.Logging.LogLevels.Warning);
            }
        }

        public async override Task<cQuickActionStatusMonitorModel> GetQuickActionStatusMonitorDataAsync()
        {
            try
            {
                var quickActionSteps = new List<cQuickActionStatusMonitorModel.cQuickActionStep>();

                bool requiresUserPermission = false;

                foreach (var quickActionConfig in chainedQuickActionConfigs)
                {
                    var tempStep = new cQuickActionStatusMonitorModel.cQuickActionStep(quickActionConfig.Names.GetValue(), quickActionConfig.Name, cQuickActionStatusMonitorModel.cQuickActionStep.enumActionStepType.main);

                    var uiAction = cUiActionBase.GetUiAction(quickActionConfig);
                    if (uiAction is cUiQuickAction uiQuickAction)
                    {
                        var statusMonitorData = await uiQuickAction.GetQuickActionStatusMonitorDataAsync();
                        tempStep.SubSteps = statusMonitorData.ActionSteps;

                        requiresUserPermission = requiresUserPermission || statusMonitorData.RequiresUserPermission;
                    }

                    quickActionSteps.Add(tempStep);

                }

                var output = new cQuickActionStatusMonitorModel()
                {
                    ActionName = ChainedQuickAction.Names.GetValue(),
                    QuickActionDefinition = ChainedQuickAction,
                    ActionSteps = quickActionSteps,
                    RequiresUserPermission = requiresUserPermission,
                    RunQuickAction = ProcessActionAsync
                };

                if (chainedQuickActionConfigs.Any(config => config.AdjustableParameters?.Count > 0))
                    output.QuickActionParameters = new Dictionary<string, cAdjustableParameter>();

                foreach (var quickActionConfig in chainedQuickActionConfigs)
                {
                    if (quickActionConfig.AdjustableParameters is null)
                        continue;

                    foreach (var quickActionParam in quickActionConfig.AdjustableParameters)
                    {
                        if (output.QuickActionParameters is null || output.QuickActionParameters.ContainsKey(quickActionParam.Key))
                            continue;

                        output.QuickActionParameters.Add(quickActionParam.Key, quickActionParam.Value);
                    }
                }

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

            return null;
        }

        public override async Task<cDataCanvasDataModel> GetQuickActionDataAsync(cSupportCaseDataProvider dataProvider, bool isDetailedLayout)
        {
            DataProvider = dataProvider;

            var detailedData = new cDetailedDataModel() { Heading = cMultiLanguageSupport.GetItem("DetailsPage.History") };

            //Get QuickAciton Data
            detailedData.FullDetailedData = new List<object>() { new List<object>() { "Status", cMultiLanguageSupport.GetItem("QuickAction.Revision.ExecutionTime") } };
            if (dataProvider != null)
            {
                var quickActionHistory = await dataProvider.QuickActionProtocollHelper.GetQuickActionHistoryAsync(ChainedQuickAction.Name);
                foreach (var historyLine in quickActionHistory)
                {
                    detailedData.FullDetailedData.Add(historyLine);
                }
            }

            //Get Process Steps of Action
            var quickActionData = await GetQuickActionStatusMonitorDataAsync();

            //Get Recommendation
            cRecommendationDataModel recommendationData = QuickActionRecommendation?.Recommendation != null ? QuickActionRecommendation : null;

            return new cDataCanvasDataModel() { DetailedData = detailedData, QuickActionStatusMonitorData = quickActionData, RecommendationData = recommendationData };
        }

        private void CancelRunningActionSteps()
        {
            try
            {
                foreach (var actionStep in StatusMonitor.QuickActionData.ActionSteps)
                {
                    if (actionStep.Status is enumQuickActionRevisionStatus.inProgress)
                        actionStep.Status = enumQuickActionRevisionStatus.canceled;

                    foreach (var subSteps in actionStep.SubSteps)
                    {
                        if (subSteps.Status is enumQuickActionRevisionStatus.inProgress)
                            subSteps.Status = enumQuickActionRevisionStatus.canceled;
                    }
                }
            }
            catch (Exception E)
            {
                LogException(E);
            }
        }

        public override async Task<List<object>> ProcessActionAsync(CancellationToken token, Dictionary<cAdjustableParameter, object> ParameterDictionary = null)
        {
            try
            {
                if (chainedQuickActionConfigs?.Count <= 0)
                    return null;

                foreach (var quickActionConfig in chainedQuickActionConfigs)
                {
                    if (token.IsCancellationRequested)
                        break;

                    var uiAction = GetUiAction(quickActionConfig);

                    if (uiAction is null)
                        continue;

                    if (!(uiAction is cUiQuickAction uiQuickAction))
                        continue;

                    uiQuickAction.DataProvider = DataProvider;
                    uiQuickAction.StatusMonitor = StatusMonitor;

                    foreach (var child in StatusMonitor.CompletionStatusPanel.Children)
                    {
                        if (child is System.Windows.Controls.StackPanel childStackPanel)
                            childStackPanel.Visibility = System.Windows.Visibility.Collapsed;

                        if (child is System.Windows.FrameworkElement childFrameworkElement)
                            if (childFrameworkElement.Tag?.Equals(quickActionConfig.Name) ?? false)
                                childFrameworkElement.Visibility = System.Windows.Visibility.Visible;
                    }

                    var result = await uiQuickAction.ProcessActionAsync(token, ParameterDictionary);

                    if (result != null && result[0].Equals(cMultiLanguageSupport.GetItem("QuickAction.Revision.Status.FinishedWithError")))
                    {
                        CancelRunningActionSteps();
                        return new List<object>() { cMultiLanguageSupport.GetItem("QuickAction.Revision.Status.FinishedWithError"), cUtility.RawValueFormatter.GetDisplayValue(DateTime.UtcNow, RawValueType.DATETIME) };
                    }
                }

                if (token.IsCancellationRequested)
                {
                    CancelRunningActionSteps();
                    return new List<object>() { cMultiLanguageSupport.GetItem("QuickAction.Revision.Status.Canceled"), cUtility.RawValueFormatter.GetDisplayValue(DateTime.UtcNow, RawValueType.DATETIME) };
                }

                return new List<object>() { cMultiLanguageSupport.GetItem("QuickAction.Revision.Status.FinishedSuccessfull"), cUtility.RawValueFormatter.GetDisplayValue(DateTime.UtcNow, RawValueType.DATETIME) };
            }
            catch (Exception E)
            {
                LogException(E);
            }

            return null;
        }
    }
}
