using MainShell.Common;
using MainShell.Log;
using MainShell.Motion;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;

namespace MainShell.PageCalib.OriginCalib.Service
{
    /// <summary>
    /// 示例后处理器：用于在标定轴移动到位后拍照
    /// </summary>
    public class VisionCapturePostProcessor : ICalibrationPostProcessor
    {
        public string Name => "VisionCapture";

        public async Task ExecuteAsync(OriginCalibrationExecutionResult calibrationResult, CancellationToken cancellationToken,object pars= null)
        {
            "执行拍照后处理逻辑...".LogInfo();

            // 在此处添加拍照逻辑
            // 例如：await _visionService.CaptureAsync(cancellationToken);

            await Task.Delay(100, cancellationToken);

            "拍照后处理完成。".LogInfo();
        }

    }

    /// <summary>
    /// 逼近对齐后处理器：用于在标定轴移动到位后执行逼近对齐
    /// </summary>
    public class ApproachAlignmentPostProcessor : ICalibrationPostProcessor
    {
        private readonly ApproachAlignmentService _approachAlignmentService;
        private readonly IReadOnlyList<ApproachAlignmentAxis> _alignmentAxes;
        private readonly CameraType _camera;

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="approachAlignmentService">逼近对齐服务</param>
        /// <param name="alignmentAxes">需要对齐的轴配置列表</param>
        /// <param name="camera">相机类型，默认为上相机</param>
        public ApproachAlignmentPostProcessor(
            ApproachAlignmentService approachAlignmentService,
            IEnumerable<ApproachAlignmentAxis> alignmentAxes,
            CameraType camera = CameraType.TopPositionCamera)
        {
            _approachAlignmentService = approachAlignmentService ?? throw new ArgumentNullException(nameof(approachAlignmentService));

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

            _alignmentAxes = alignmentAxes.ToList().AsReadOnly();

            if (_alignmentAxes.Count == 0)
            {
                throw new ArgumentException("至少需要一个对齐轴。", nameof(alignmentAxes));
            }

            _camera = camera;
        }

        public string Name => "ApproachAlignment";

        public async Task ExecuteAsync(OriginCalibrationExecutionResult calibrationResult, CancellationToken cancellationToken,object pars= null)
        {
            "执行逼近对齐后处理逻辑...".LogInfo();

            try
            {
                ApproachAlignmentRequest alignmentRequest = new ApproachAlignmentRequest(_alignmentAxes, _camera);
                if(pars is CenterRecognitionParameters centerRecognitionParameters)
                {
                    alignmentRequest.RecognitionParameters = centerRecognitionParameters;
                }

                ApproachAlignmentResult alignmentResult = await _approachAlignmentService.ApproachAlignmentAsync(
                    alignmentRequest,
                    cancellationToken).ConfigureAwait(false);

                if (alignmentResult.Succeeded)
                {
                    string.Format("逼近对齐完成，迭代次数：{0}", alignmentResult.CompletedIterations).LogInfo();
                }
                else
                {
                    string.Format("逼近对齐失败：{0}", alignmentResult.Message).LogInfo();
                    throw alignmentResult.Exception ?? new InvalidOperationException(alignmentResult.Message);
                }
            }
            catch (OperationCanceledException)
            {
                "逼近对齐后处理被取消。".LogInfo();
                throw;
            }
            catch (Exception ex)
            {
                string.Format("逼近对齐后处理异常：{0}", ex.Message).LogInfo();
                throw;
            }
        }
    }

    /// <summary>
    /// 单次对位后处理器：用于在标定轴移动到位后执行一次识别、转换与运动
    /// </summary>
    public class SingleAlignmentPostProcessor : ICalibrationPostProcessor
    {
        private readonly ApproachAlignmentService _approachAlignmentService;
        private readonly IReadOnlyList<ApproachAlignmentAxis> _alignmentAxes;
        private readonly CameraType _camera;

        public SingleAlignmentPostProcessor(
            ApproachAlignmentService approachAlignmentService,
            IEnumerable<ApproachAlignmentAxis> alignmentAxes,
            CameraType camera = CameraType.TopPositionCamera)
        {
            _approachAlignmentService = approachAlignmentService ?? throw new ArgumentNullException(nameof(approachAlignmentService));

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

            _alignmentAxes = alignmentAxes.ToList().AsReadOnly();

            if (_alignmentAxes.Count == 0)
            {
                throw new ArgumentException("至少需要一个对齐轴。", nameof(alignmentAxes));
            }

            _camera = camera;
        }

        public string Name => "SingleAlignment";

        public async Task ExecuteAsync(OriginCalibrationExecutionResult calibrationResult, CancellationToken cancellationToken, object pars = null)
        {
            "执行单次对位后处理逻辑...".LogInfo();

            try
            {
                ApproachAlignmentRequest alignmentRequest = new ApproachAlignmentRequest(_alignmentAxes, _camera);
                if (pars is CenterRecognitionParameters centerRecognitionParameters)
                {
                    alignmentRequest.RecognitionParameters = centerRecognitionParameters;
                }

                ApproachAlignmentResult alignmentResult = await _approachAlignmentService.SingleAlignmentAsync(
                    alignmentRequest,
                    cancellationToken).ConfigureAwait(false);

                if (alignmentResult.Succeeded)
                {
                    string.Format("单次对位完成，执行次数：{0}", alignmentResult.CompletedIterations).LogInfo();
                }
                else
                {
                    string.Format("单次对位失败：{0}", alignmentResult.Message).LogInfo();
                    throw alignmentResult.Exception ?? new InvalidOperationException(alignmentResult.Message);
                }
            }
            catch (OperationCanceledException)
            {
                "单次对位后处理被取消。".LogInfo();
                throw;
            }
            catch (Exception ex)
            {
                string.Format("单次对位后处理异常：{0}", ex.Message).LogInfo();
                throw;
            }
        }
    }
}
