using MW.WorkFlow;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;

namespace MW.WorkFlow
{
   
    /// <summary>
    /// 负责执行工作流活动，并支持暂停、恢复、停止、重启和跳转，基于工作流定义和取消功能。
    /// </summary>
    public class WorkflowEngine : IDisposable
    {
        private const string WorkflowNameContextKey = "WorkflowName";
        private const string ParentActivityNameContextKey = "ParentActivityName";
        private const string CurrentStepIdContextKey = "CurrentStepId";
        private const string NextStepIdContextKey = "NextStepId";
        private const string WorkflowRuntimeTrackerContextKey = "WorkflowRuntimeTracker";
        private const string WorkflowFailureMessageContextKey = "WorkflowFailureMessage";
        private const string WorkflowFailureMessageKeyContextKey = "WorkflowFailureMessageKey";
        private const string WorkflowFailureMessageArgumentsContextKey = "WorkflowFailureMessageArguments";

        private readonly WorkflowDefinition _workflowDefinition;
        private readonly WorkflowContext _context;
        private string _currentStepId;
        private volatile bool _isPausedRequested; // 外部请求暂停的标志
        private TaskCompletionSource<bool> _currentPauseSignal; // 当前的暂停信号
        private CancellationTokenSource _workflowCancellationTokenSource;
        private Task _workflowExecutionTask;
        private bool disposedValue;
        private readonly object _stateLock = new object(); // 用于保护共享状态的锁

        // 当前工作流的状态
        public WorkflowState CurrentState { get; private set; } = WorkflowState.Created;
        public bool IsWorkflowPaused => _isPausedRequested;
        public bool IsWorkflowFinished => _currentStepId == null;
        public bool IsWorkflowRunning => _workflowExecutionTask != null && !_workflowExecutionTask.IsCompleted;
        public string CurrentStepId => _currentStepId;
        public Exception LastException { get; private set; }

        public WorkflowEngine(WorkflowDefinition workflowDefinition, WorkflowContext context)
        {
            _workflowDefinition = workflowDefinition ?? throw new ArgumentNullException(nameof(workflowDefinition));
            _context = context ?? throw new ArgumentNullException(nameof(context));
            _currentStepId = workflowDefinition.InitialStepId;
            _isPausedRequested = false;

            _currentPauseSignal = new TaskCompletionSource<bool>(TaskCreationOptions.RunContinuationsAsynchronously);
            _currentPauseSignal.SetResult(true); // 初始时已经完成
        }

        // 启动工作流的执行，可选参数允许指定起始步骤
        public void Start(string startStepId = null)
        {
            lock (_stateLock)
            {
                if (IsWorkflowRunning)
                {
                    Debug.WriteLine("[WorkflowEngine] 工作流已经在运行中，无法重复启动。");
                    return;
                }

                // 核心修改逻辑：处理起始步骤
                if (!string.IsNullOrEmpty(startStepId))
                {
                    // 验证步骤是否存在
                    if (!_workflowDefinition.ContainsStep(startStepId))
                    {
                        throw new ArgumentException($"指定的起始步骤ID '{startStepId}' 不存在于工作流定义中。", nameof(startStepId));
                    }
                    _currentStepId = startStepId;
                }
                else if (_currentStepId == null)
                {
                    // 如果未指定且当前没有步骤（例如上次运行已结束），重置为初始步骤
                    _currentStepId = _workflowDefinition.InitialStepId;
                }

                LastException = null;
                UpdateWorkflowState(WorkflowState.Running);
                _isPausedRequested = false;
                _workflowCancellationTokenSource?.Dispose();
                _workflowCancellationTokenSource = new CancellationTokenSource();

                // 确保 _currentPauseSignal 处于已完成状态，以便工作流立即开始
                if (!_currentPauseSignal.Task.IsCompleted)
                {
                    _currentPauseSignal.TrySetResult(true);
                }

                // 使用 Task.Run(ExecuteWorkflowInternalAsync) 避免嵌套 Task<Task>
                _workflowExecutionTask = Task.Run(ExecuteWorkflowInternalAsync);
                // 注册仅在发生未处理异常时的续体以记录异常，避免未观察异常
                _workflowExecutionTask.ContinueWith(t =>
                {
                    Debug.WriteLine($"[WorkflowEngine] 工作流任务发生未处理异常: {t.Exception?.Flatten().InnerException}");
                }, TaskContinuationOptions.OnlyOnFaulted);
                Debug.WriteLine($"[WorkflowEngine] 工作流已启动，从步骤 '{_currentStepId}' 开始。");
            }
        }

        // 异步执行工作流中的活动
        private async Task ExecuteWorkflowInternalAsync()
        {
            Debug.WriteLine("\n[WorkflowEngine] 工作流执行开始。");
            CancellationToken cancellationToken = _workflowCancellationTokenSource.Token;

           
            Func<Task> pauseCheck = async () =>
            {
                cancellationToken.ThrowIfCancellationRequested();

                if (_isPausedRequested)
                {
                    Debug.WriteLine("[WorkflowEngine] 工作流已暂停，等待恢复...");
                    var pauseTask = _currentPauseSignal.Task;
                    var cancelTask = Task.Delay(Timeout.Infinite, cancellationToken);
                    var finished = await Task.WhenAny(pauseTask, cancelTask).ConfigureAwait(false);
                    if (finished == cancelTask)
                    {
                        // 如果取消任务先完成，则抛出取消
                        cancellationToken.ThrowIfCancellationRequested();
                    }
                    // 等待 pauseTask 以传播其可能的异常/取消
                    await pauseTask.ConfigureAwait(false);
                    Debug.WriteLine("[WorkflowEngine] 工作流已恢复。");
                }
            };
            ActivityControl activityControl = new ActivityControl(cancellationToken, pauseCheck);
            WorkflowStep currentStep = null;
            try
            {
                while (_currentStepId != null)
                {
                    cancellationToken.ThrowIfCancellationRequested();
                    await pauseCheck().ConfigureAwait(false);

                    try
                    {
                        currentStep = _workflowDefinition.GetStep(_currentStepId);
                    }
                    catch (ArgumentException ex)
                    {
                        Debug.WriteLine($"[WorkflowEngine] 错误：无法找到步骤ID '{_currentStepId}'。工作流终止。原因: {ex.Message}");
                        HandleWorkflowFault(ex, currentStep);
                        _currentStepId = null;
                        break;
                    }

                    IActivity currentActivity = currentStep.Activity;
                    _context.SetData(WorkflowFailureMessageContextKey, string.Empty);
                    _context.SetData<object>(WorkflowFailureMessageKeyContextKey, null);
                    _context.SetData<object[]>(WorkflowFailureMessageArgumentsContextKey, null);
                    UpdateExecutionContext(currentStep);
                    TrackExecutionPointer(currentStep, currentStep.Id);
                    Debug.WriteLine($"\n[WorkflowEngine] 执行步骤: {currentStep.Id}, 活动: {currentActivity.Name}");

                    ActivityResult result = ActivityResult.Failure;
                    try
                    {
                        result = await currentActivity.ExecuteAsync(_context, activityControl).ConfigureAwait(false);
                    }
                    catch (OperationCanceledException)
                    {
                        Debug.WriteLine($"[WorkflowEngine] 活动 '{currentActivity.Name}' 被取消。");
                        result = ActivityResult.Canceled;
                        if (CurrentState != WorkflowState.Stopped)
                        {
                            UpdateWorkflowState(WorkflowState.Canceled);
                        }
                        break;
                    }
                    catch (Exception ex)
                    {
                        Debug.WriteLine($"[WorkflowEngine] 活动 '{currentActivity.Name}' 执行时发生未处理的异常: {ex.Message}");
                        result = ActivityResult.Failure;
                        HandleWorkflowFault(ex, currentStep);
                        break;
                    }

                    Debug.WriteLine($"[WorkflowEngine] 步骤 '{currentStep.Id}' 完成，结果: {result}");

                    // 如果状态已变为 Faulted (可能在上面的 catch 中没 break 住，或者其他逻辑导致)，双重保险停止
                    if (CurrentState == WorkflowState.Faulted || CurrentState == WorkflowState.Canceled)
                    {
                        break;
                    }

                    if (result == ActivityResult.Failure)
                    {
                        string failureMessage = ResolveWorkflowFailureMessage(currentActivity.Name);
                        Debug.WriteLine($"[WorkflowEngine] {failureMessage}");
                        HandleWorkflowFailure(failureMessage, currentStep);
                        break;
                    }

                    string nextStepCandidateId = null;

                    foreach (var condition in currentStep.JumpConditions)
                    {
                        if (condition.Condition(_context, result))
                        {
                            nextStepCandidateId = condition.ResolveTargetStepId(_context, result);
                            Debug.WriteLine($"[WorkflowEngine] 条件跳转满足，跳转到步骤 '{nextStepCandidateId}'。");
                            break;
                        }
                    }

                    if (nextStepCandidateId == null && !string.IsNullOrEmpty(currentStep.NextStepId))
                    {
                        nextStepCandidateId = currentStep.NextStepId;
                        Debug.WriteLine($"[WorkflowEngine] 默认跳转，跳转到步骤 '{nextStepCandidateId}'。");
                    }

                    if (!string.IsNullOrWhiteSpace(nextStepCandidateId) && !_workflowDefinition.ContainsStep(nextStepCandidateId))
                    {
                        throw new InvalidOperationException($"步骤 '{currentStep.Id}' 解析出的目标步骤 '{nextStepCandidateId}' 不存在于工作流定义中。");
                    }

                    TrackExecutionPointer(currentStep, nextStepCandidateId);

                    lock (_stateLock)
                    {
                        if (_currentStepId == currentStep.Id)
                        {
                            _currentStepId = nextStepCandidateId;
                        }
                        else
                        {
                            Debug.WriteLine($"[WorkflowEngine] 外部已修改当前步骤，跳过内部跳转逻辑。");
                        }
                    }

                    if (_currentStepId == null)
                    {
                        UpdateWorkflowState(WorkflowState.Completed);
                        Debug.WriteLine($"[WorkflowEngine] 工作流已完成。");
                    }
                }
            }
            catch (OperationCanceledException)
            {
                Debug.WriteLine("[WorkflowEngine] 工作流执行被取消。");
                if (CurrentState != WorkflowState.Stopped)
                {
                    UpdateWorkflowState(WorkflowState.Canceled);
                }
            }
            catch (Exception ex)
            {
                Debug.WriteLine($"[WorkflowEngine] 工作流执行过程中发生未处理的异常: {ex.Message}");
                HandleWorkflowFault(ex, currentStep);
            }
            finally
            {
                Debug.WriteLine("[WorkflowEngine] 工作流执行结束。");
                lock (_stateLock)
                {
                    _workflowExecutionTask = null;
                    _currentStepId = null;
                    _workflowCancellationTokenSource?.Dispose();
                    _workflowCancellationTokenSource = null;
                }
            }
        }

        // 更新工作流状态，并记录日志
        private void UpdateWorkflowState(WorkflowState newState)
        {
            if (CurrentState != newState)
            {
                CurrentState = newState;
                Debug.WriteLine($"[WorkflowEngine] 工作流状态已更改: {CurrentState}");
            }
        }

        private void HandleWorkflowFault(Exception ex, WorkflowStep currentStep)
        {
            LastException = ex;
            UpdateWorkflowState(WorkflowState.Faulted);

            if (_context.TryGetData<IWorkflowRuntimeTracker>(WorkflowRuntimeTrackerContextKey, out var tracker) && tracker != null)
            {
                _context.TryGetData<string>(WorkflowNameContextKey, out var workflowName);
                _context.TryGetData<string>(ParentActivityNameContextKey, out var flowNameFromContext);
                _context.TryGetData<string>(CurrentStepIdContextKey, out var currentStepIdFromContext);

                tracker.ReportWorkflowFault(new WorkflowFaultInfo
                {
                    WorkflowName = workflowName,
                    FlowName = currentStep?.FlowName ?? flowNameFromContext,
                    ActivityName = currentStep?.Activity?.Name,
                    CurrentStepId = currentStep?.Id ?? currentStepIdFromContext ?? _currentStepId,
                    ErrorMessage = ex?.Message,
                    OccurredAt = DateTime.Now
                });
            }
        }

        private void HandleWorkflowFailure(string errorMessage, WorkflowStep currentStep)
        {
            LastException = new InvalidOperationException(errorMessage);
            UpdateWorkflowState(WorkflowState.Faulted);

            if (_context.TryGetData<IWorkflowRuntimeTracker>(WorkflowRuntimeTrackerContextKey, out var tracker) && tracker != null)
            {
                _context.TryGetData<string>(WorkflowNameContextKey, out var workflowName);
                _context.TryGetData<string>(ParentActivityNameContextKey, out var flowNameFromContext);
                _context.TryGetData<string>(CurrentStepIdContextKey, out var currentStepIdFromContext);

                tracker.ReportWorkflowFault(new WorkflowFaultInfo
                {
                    WorkflowName = workflowName,
                    FlowName = currentStep?.FlowName ?? flowNameFromContext,
                    ActivityName = currentStep?.Activity?.Name,
                    CurrentStepId = currentStep?.Id ?? currentStepIdFromContext ?? _currentStepId,
                    ErrorMessage = errorMessage,
                    OccurredAt = DateTime.Now
                });
            }
        }

        private string ResolveWorkflowFailureMessage(string activityName)
        {
            string failureMessage;
            if (_context.TryGetData<string>(WorkflowFailureMessageContextKey, out failureMessage) &&
                !string.IsNullOrWhiteSpace(failureMessage))
            {
                return failureMessage;
            }

            return $"活动 '{activityName}' 返回 Failure，工作流按失败结束。";
        }

        private void UpdateExecutionContext(WorkflowStep currentStep)
        {
            _context.SetData(CurrentStepIdContextKey, currentStep.Id);
            _context.SetData(NextStepIdContextKey, currentStep.Id);
            _context.SetData(ParentActivityNameContextKey, currentStep.FlowName ?? string.Empty);
        }

        private void TrackExecutionPointer(WorkflowStep currentStep, string nextStepId)
        {
            _context.SetData(NextStepIdContextKey, nextStepId);

            if (_context.TryGetData<IWorkflowRuntimeTracker>(WorkflowRuntimeTrackerContextKey, out var tracker) && tracker != null)
            {
                _context.TryGetData<string>(WorkflowNameContextKey, out var workflowName);
                tracker.UpdateExecutionPointer(new WorkflowExecutionPointer
                {
                    WorkflowName = workflowName,
                    FlowName = currentStep?.FlowName,
                    ActivityName = currentStep?.Activity?.Name,
                    CurrentStepId = currentStep?.Id,
                    NextStepId = nextStepId,
                    UpdatedAt = DateTime.Now
                });
            }
        }

        // 暂停工作流
        public void Pause()
        {
            
            lock (_stateLock)
            {
                if (!IsWorkflowRunning)
                {
                    Debug.WriteLine("[WorkflowEngine] 工作流未运行，无法暂停。");
                    return;
                }
                if (_isPausedRequested)
                {
                    Debug.WriteLine("[WorkflowEngine] 工作流已处于暂停状态。");
                    return;
                }

                UpdateWorkflowState(WorkflowState.Paused);
                _isPausedRequested = true;
                if (_currentPauseSignal.Task.IsCompleted)
                {
                    _currentPauseSignal = new TaskCompletionSource<bool>(TaskCreationOptions.RunContinuationsAsynchronously);
                }
                Debug.WriteLine("[WorkflowEngine] 工作流已请求暂停。");
            }
        }

        // 恢复工作流
        public void Resume()
        {
            lock (_stateLock)
            {
                if (_isPausedRequested)
                {
                    _currentPauseSignal.TrySetResult(true);
                    _isPausedRequested = false;
                    UpdateWorkflowState(WorkflowState.Running);
                    Debug.WriteLine("[WorkflowEngine] 工作流已恢复。");
                }
                else
                {
                    Debug.WriteLine("[WorkflowEngine] 工作流未暂停，无需恢复。");
                }
            }
        }

        // 停止工作流
        public async Task StopAsync()
        {
            Task taskToAwait = null;
            lock (_stateLock)
            {
                if (!IsWorkflowRunning)
                {
                    Debug.WriteLine("[WorkflowEngine] 工作流未运行，无法停止。");
                    return;
                }

                if (_workflowCancellationTokenSource?.IsCancellationRequested == true)
                {
                    taskToAwait = _workflowExecutionTask;
                }
                else
                {
                    Debug.WriteLine("[WorkflowEngine] 已请求停止工作流。");
                    UpdateWorkflowState(WorkflowState.Stopped);
                    _workflowCancellationTokenSource?.Cancel();
                    if (_isPausedRequested)
                    {
                        Resume();
                    }
                    taskToAwait = _workflowExecutionTask;
                }
            }

            if (taskToAwait != null)
            {
                try
                {
                    await taskToAwait.ConfigureAwait(false);
                }
                catch (OperationCanceledException)
                {
                    Debug.WriteLine("[WorkflowEngine] 工作流任务被取消。");
                }
                catch (Exception ex)
                {
                    Debug.WriteLine($"[WorkflowEngine] 停止工作流时发生异常: {ex.Message}");
                }
            }

            lock (_stateLock)
            {
                _workflowExecutionTask = null;
                _currentStepId = null;
                _workflowCancellationTokenSource?.Dispose();
                _workflowCancellationTokenSource = null;
                _isPausedRequested = false;
                Debug.WriteLine("[WorkflowEngine] 工作流已停止。");
            }
        }

        // 重启工作流
        public async Task RestartAsync(string startFromStepId = null, bool clearContext = true)
        {
            await StopAsync().ConfigureAwait(false);
            lock (_stateLock)
            {
                if (clearContext)
                {
                    _context.Clear();
                }

                _currentStepId = startFromStepId ?? _workflowDefinition.InitialStepId;
            }
            Start();
        }

        // 跳转到指定步骤
        public void JumpTo(string stepId)
        {
            lock (_stateLock)
            {
                if (!_workflowDefinition.GetAllStepIds().Contains(stepId))
                {
                    throw new ArgumentException($"步骤ID '{stepId}' 不存在。", nameof(stepId));
                }

                _currentStepId = stepId;
                var step = _workflowDefinition.GetStep(stepId);
                UpdateExecutionContext(step);
                TrackExecutionPointer(step, stepId);
                Debug.WriteLine($"[WorkflowEngine] 跳转到步骤 '{stepId}'。");

                if (IsWorkflowPaused)
                {
                    Resume();
                }
            }
        }

        // 将异步 Dispose 改为同步；在 .NET Framework 中不要在 Dispose 中使用 async void/Task 未等待
        protected virtual void Dispose(bool disposing)
        {
            if (!disposedValue)
            {
                if (disposing)
                {
                    if (IsWorkflowRunning)
                    {
                        // 同步等待 StopAsync 完成以确保资源清理
                        StopAsync().GetAwaiter().GetResult();
                    }
                }
                disposedValue = true;
            }
        }

        public void Dispose()
        {
            Dispose(disposing: true);
            GC.SuppressFinalize(this);
        }
    }

}
