using MainShell.Common;
using MainShell.EventArgsFolder;
using MainShell.Process;
using Stylet;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using MW.WorkFlow;

namespace MainShell.ProcessResult
{
    public class ProcessResultManager
    {
        private readonly MachineState _machineState;
        private readonly IEventAggregator _eventAggregator;

        /// <summary>
        /// 流程运行状态记录（仅在自动模式下持久化）
        /// </summary>
        public ProcessFlowState FlowState { get; } = new ProcessFlowState();

        /// <summary>
        /// 基板定位的业务结果数据（始终持久化）
        /// </summary>
        public SubstratePositionProcessResult SubstratePositionResult { get; } = new SubstratePositionProcessResult();

        /// <summary>
        /// 芯片定位的业务结果数据（始终持久化）
        /// </summary>
        public DiePositionProcessResult DiePositionResult { get; } = new DiePositionProcessResult();

        /// <summary>
        /// 基板测高的业务结果数据（始终持久化）
        /// </summary>
        public SubstrateHeightMeasureProcessResult SubstrateHeightMeasureResult { get; } = new SubstrateHeightMeasureProcessResult();

        /// <summary>
        /// 精度复检的业务结果数据（始终持久化）
        /// </summary>
        public DieRecheckProcessResult DieRecheckResult { get; } = new DieRecheckProcessResult();

        /// <summary>
        /// 首页统计与条码展示状态（始终持久化）
        /// </summary>
        public ProductionDashboardState DashboardState { get; } = new ProductionDashboardState();

        /// <summary>
        /// 准备区状态（用于恢复前一致性校验）
        /// </summary>
        public PreparationAreaProcessState PreparationAreaState { get; } = new PreparationAreaProcessState();

        private readonly AutoProductionResumeValidator _resumeValidator = new AutoProductionResumeValidator();

        /// <summary>
        /// 当前芯片使用位状态
        /// </summary>
        public CurrentChipProcessState CurrentChipState { get; } = new CurrentChipProcessState();

        /// <summary>
        /// 自动流程运行态
        /// </summary>
        public AutoProductionRuntimeState AutoProductionRuntimeState { get; } = new AutoProductionRuntimeState();

        public ProcessResultManager(MachineState machineState, IEventAggregator eventAggregator)
        {
            _machineState = machineState ?? throw new ArgumentNullException(nameof(machineState));
            _eventAggregator = eventAggregator ?? throw new ArgumentNullException(nameof(eventAggregator));
            // 构造时读取一次
            ReloadAll();
        }

        public void UpdateFlowState(string workflowName, string parentActivityName, string activityName, ProcessExecutionStatus status, string errorMessage = null)
        {
            FlowState.WorkflowName = workflowName;
            FlowState.ParentActivityName = parentActivityName;
            FlowState.CurrentActivityName = activityName;
            FlowState.Status = status.ToString();
            FlowState.ErrorMessage = errorMessage;
            FlowState.LastUpdateTime = DateTime.Now;

            if (ShouldPersistFlowState(workflowName))
            {
                FlowState.Write();
            }

            _eventAggregator.Publish(new ProcessFlowStateChangedEventArgs
            {
                WorkflowName = workflowName,
                ParentActivityName = parentActivityName,
                CurrentActivityName = activityName,
                Status = status,
                ErrorMessage = errorMessage
            });
        }

        public void UpdateFlowState(string workflowName, string parentActivityName, string activityName, string status, string errorMessage = null)
        {
            ProcessExecutionStatus parsed;
            if (!Enum.TryParse(status, true, out parsed))
            {
                parsed = ProcessExecutionStatus.Unknown;
            }

            UpdateFlowState(workflowName, parentActivityName, activityName, parsed, errorMessage);
        }

        public void UpdateExecutionPointer(WorkflowExecutionPointer executionPointer)
        {
            if (executionPointer == null)
            {
                return;
            }

            FlowState.WorkflowName = executionPointer.WorkflowName;
            FlowState.ParentActivityName = executionPointer.FlowName;
            FlowState.CurrentActivityName = executionPointer.ActivityName;
            FlowState.CurrentStepId = executionPointer.CurrentStepId;
            FlowState.NextStepId = executionPointer.NextStepId;
            FlowState.LastUpdateTime = executionPointer.UpdatedAt == default(DateTime) ? DateTime.Now : executionPointer.UpdatedAt;

            if (ShouldPersistFlowState(executionPointer.WorkflowName))
            {
                FlowState.Write();
            }

        }

        public void ReportWorkflowFault(WorkflowFaultInfo faultInfo)
        {
            if (faultInfo == null)
            {
                return;
            }

            FlowState.WorkflowName = faultInfo.WorkflowName;
            FlowState.ParentActivityName = faultInfo.FlowName;
            FlowState.CurrentActivityName = faultInfo.ActivityName;
            FlowState.CurrentStepId = faultInfo.CurrentStepId;
            FlowState.NextStepId = faultInfo.CurrentStepId;
            FlowState.Status = ProcessExecutionStatus.Faulted.ToString();
            FlowState.ErrorMessage = faultInfo.ErrorMessage;
            FlowState.LastUpdateTime = faultInfo.OccurredAt == default(DateTime) ? DateTime.Now : faultInfo.OccurredAt;

            if (ShouldPersistFlowState(faultInfo.WorkflowName))
            {
                FlowState.Write();
            }
            _eventAggregator.Publish(new ProcessFlowStateChangedEventArgs
            {
                WorkflowName = faultInfo.WorkflowName,
                ParentActivityName = faultInfo.FlowName,
                CurrentActivityName = faultInfo.ActivityName,
                Status = ProcessExecutionStatus.Faulted,
                ErrorMessage = faultInfo.ErrorMessage
            });

        }

        public bool TryGetResumeStepId(string workflowName, out string resumeStepId)
        {
            resumeStepId = null;

            if (string.IsNullOrWhiteSpace(workflowName) ||
                !string.Equals(FlowState.WorkflowName, workflowName, StringComparison.OrdinalIgnoreCase) ||
                string.IsNullOrWhiteSpace(FlowState.NextStepId))
            {
                return false;
            }

            if (string.Equals(FlowState.Status, ProcessExecutionStatus.Completed.ToString(), StringComparison.OrdinalIgnoreCase) ||
                string.Equals(FlowState.Status, ProcessExecutionStatus.Canceled.ToString(), StringComparison.OrdinalIgnoreCase))
            {
                return false;
            }

            if (!_resumeValidator.IsStateConsistentForResume(FlowState.NextStepId, PreparationAreaState, CurrentChipState))
            {
                FlowState.ErrorMessage = _resumeValidator.BuildResumeValidationError(FlowState.NextStepId, PreparationAreaState, CurrentChipState);
                FlowState.LastUpdateTime = DateTime.Now;
                if (ShouldPersistFlowState(workflowName))
                {
                    FlowState.Write();
                }
                return false;
            }

            resumeStepId = FlowState.NextStepId;
            return true;
        }

        public void SaveSubstratePositionResult()
        {
            SubstratePositionResult.Write();
        }

        public void SaveDiePositionResult()
        {
            DiePositionResult.Write();
        }

        public void SaveSubstrateHeightMeasureResult()
        {
            SubstrateHeightMeasureResult.Write();
        }

        public void SaveDieRecheckResult()
        {
            DieRecheckResult.Write();
        }

        public void SaveDashboardState()
        {
            DashboardState.Write();
        }

        public void SavePreparationAreaState(ChipPreparationStateSnapshot snapshot)
        {
            if (snapshot == null)
            {
                return;
            }

            PreparationAreaState.Status = snapshot.Status;
            PreparationAreaState.ActiveRequestId = snapshot.ActiveRequestId;
            PreparationAreaState.RecipeName = snapshot.RecipeName;
            PreparationAreaState.SourceStepId = snapshot.SourceStepId;
            PreparationAreaState.CurrentStage = snapshot.CurrentStage;
            PreparationAreaState.ErrorMessage = snapshot.ErrorMessage;
            PreparationAreaState.LastUpdatedTime = snapshot.LastUpdatedTime;
            PreparationAreaState.CurrentAction = snapshot.CurrentAction;
            PreparationAreaState.HasPreparedChip = snapshot.IsChipLoaded;
            PreparationAreaState.Write();
        }

        public void SaveCurrentChipState(CurrentChipLifecycleState chipState)
        {
            CurrentChipState.State = chipState;
            CurrentChipState.LastUpdatedTime = DateTime.Now;
            CurrentChipState.Write();
        }

        public void SaveAutoProductionRuntimeState(AutoProductionRuntimeState runtimeState)
        {
            if (runtimeState == null)
            {
                return;
            }

            AutoProductionRuntimeState.CurrentSubstratePendingCount = runtimeState.CurrentSubstratePendingCount;
            AutoProductionRuntimeState.CurrentSubstrateProcessedCount = runtimeState.CurrentSubstrateProcessedCount;
            AutoProductionRuntimeState.CurrentChipRemainingCount = runtimeState.CurrentChipRemainingCount;
            AutoProductionRuntimeState.TransferNeedsRecheck = runtimeState.TransferNeedsRecheck;
            AutoProductionRuntimeState.TransferChipExhausted = runtimeState.TransferChipExhausted;
            AutoProductionRuntimeState.LastUpdatedTime = runtimeState.LastUpdatedTime;
            AutoProductionRuntimeState.Write();
        }

        /// <summary>
        /// 强制从磁盘重新加载所有状态和结果数据
        /// <para>在启动或恢复自动流程前调用，确保获取到最新的（可能是手动操作产生的）结果数据</para>
        /// </summary>
        public void ReloadAll()
        {
            // 1. 读取断点状态（决定从哪一步开始）
            FlowState.Read();
            
            // 2. 读取业务结果（决定流程所需的数据上下文）
            // 无论之前是手动还是自动写入的，这里统一读取最新值
            SubstratePositionResult.Read();
            DiePositionResult.Read();
            SubstrateHeightMeasureResult.Read();
            DieRecheckResult.Read();

            // 3. 首页运行数据
            DashboardState.Read();

            // 4. 准备区状态
            PreparationAreaState.Read();

            // 5. 当前芯片使用位状态
            CurrentChipState.Read();

            // 6. 自动流程运行态
            AutoProductionRuntimeState.Read();
            
            // 后续如果有其他结果类（如 WaferMapResult），也在这里读取
            // WaferMapResult.Read();
        }

        private bool ShouldPersistFlowState(string workflowName)
        {
            return _machineState.CurrentMode == MachineMode.Auto ||
                   string.Equals(workflowName, ProcessFlowName.AutoProduction, StringComparison.OrdinalIgnoreCase);
        }
    }
}
