using MainShell.Common;
using MainShell.ProcessResult;
using MW.WorkFlow;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;

namespace MainShell.Process
{
    public class DieRecheckService
    {
        public async Task ExecuteAsync(WorkflowContext context, ActivityControl activityControl)
        {
            if (context == null)
            {
                throw new ArgumentNullException(nameof(context));
            }

            if (activityControl == null)
            {
                throw new ArgumentNullException(nameof(activityControl));
            }

            ProcessResultManager processResultManager = context.GetData<ProcessResultManager>(WorkflowContextKeys.ProcessResultManager);
            DieRecheckProcessResult processResult = processResultManager.DieRecheckResult;
            processResult.IsSuccess = false;

            DieTransferPathPlan pathPlan;
            if (context.TryGetData<DieTransferPathPlan>(WorkflowContextKeys.DieTransferPathPlan, out pathPlan) && pathPlan != null)
            {
                processResult.PointResults = ConvertToPointResults(pathPlan);
            }
            else if (processResult.PointResults == null)
            {
                processResult.PointResults = new List<DieRecheckPointResult>();
            }

            for (int index = 0; index < 5; index++)
            {
                activityControl.ThrowIfCancellationRequested();
                await activityControl.CheckPauseAsync().ConfigureAwait(false);
                await Task.Delay(50, activityControl.CancellationToken).ConfigureAwait(false);
            }

            processResult.IsSuccess = true;
            processResultManager.SaveDieRecheckResult();
            context.SetData(WorkflowContextKeys.DieRecheckResult, processResult);
        }

        private static List<DieRecheckPointResult> ConvertToPointResults(DieTransferPathPlan pathPlan)
        {
            List<DieRecheckPointResult> pointResults = new List<DieRecheckPointResult>();
            if (pathPlan == null || pathPlan.Steps == null)
            {
                return pointResults;
            }

            foreach (DieTransferPathStep step in pathPlan.Steps)
            {
                if (step == null)
                {
                    continue;
                }

                pointResults.Add(new DieRecheckPointResult
                {
                    StepIndex = step.StepIndex,
                    PadRow = step.PadRow,
                    PadColumn = step.PadColumn,
                    DieRow = step.DieRow,
                    DieColumn = step.DieColumn,
                    PadX = step.PadX,
                    PadY = step.PadY,
                    DieX = step.DieX,
                    DieY = step.DieY,
                    TransPathType = step.TransPathType.ToString(),
                    IsMissingBond = false,
                    XError = step.DieX - step.PadX,
                    YError = step.DieY - step.PadY
                });
            }

            return pointResults;
        }
    }
}
