using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using MainShell.Common;
using SemiconductorVisionAlgorithm.SemiParams;

namespace MainShell.Motion
{
    #region 数据结构

    /// <summary>
    /// 逼近对位的单轴配置
    /// </summary>
    public class ApproachAlignmentAxis
    {
        public ApproachAlignmentAxis(string axisName, double toleranceValue)
        {
            if (string.IsNullOrWhiteSpace(axisName))
            {
                throw new ArgumentNullException(nameof(axisName));
            }

            if (toleranceValue <= 0)
            {
                throw new ArgumentException("Tolerance value must be positive.", nameof(toleranceValue));
            }

            AxisName = axisName;
            ToleranceValue = toleranceValue;
        }

        /// <summary>
        /// 轴名称（如 "X", "Y"）
        /// </summary>
        public string AxisName { get; }

        /// <summary>
        /// 该轴的允许误差（单位与轴位置一致，通常为 mm）
        /// </summary>
        public double ToleranceValue { get; }

        /// <summary>
        /// 轴的描述信息（用于日志）
        /// </summary>
        public string Description { get; set; }
    }

    public enum CenterRecognitionType
    {
        Template,
        EdgeCircle
    }

    public class CenterRecognitionParameters
    {


        public CenterRecognitionParameters()
        {
            MinScore = 0.8d;
            TemplatePath = "Template/Default";
            Type = CenterRecognitionType.Template;
        }

        public string TemplatePath { get; set; }

        public double MinScore { get; set; }

        public bool UseRoi { get; set; }

        public string RoiName { get; set; }

        public CenterRecognitionType Type { get; set; }

        public Rectangle1 rectangle { get; set; }
    }

   

    /// <summary>
    /// 逼近对位请求参数
    /// </summary>
    public class ApproachAlignmentRequest
    {
        private IReadOnlyList<ApproachAlignmentAxis> _axes;

        public ApproachAlignmentRequest(IEnumerable<ApproachAlignmentAxis> axes, CameraType camera = CameraType.TopPositionCamera)
        {
            if (axes == null)
            {
                throw new ArgumentNullException(nameof(axes));
            }

            var axesList = axes.ToList();
            if (axesList.Count == 0)
            {
                throw new ArgumentException("At least one axis is required.", nameof(axes));
            }

            Axes = axesList.AsReadOnly();
            Camera = camera;
            MaxIterations = 5;
            MoveTimeoutMilliseconds = 30000;
            RecognitionTimeoutMilliseconds = 100000;
            RecognitionParameters = new CenterRecognitionParameters();
        }

        /// <summary>
        /// 逼近轴配置列表
        /// </summary>
        public IReadOnlyList<ApproachAlignmentAxis> Axes
        {
            get { return _axes; }
            private set { _axes = value; }
        }

        /// <summary>
        /// 相机标识（用于采图和识别）
        /// </summary>
        public CameraType Camera { get; set; }

        /// <summary>
        /// 最大循环次数（默认 5）
        /// </summary>
        public int MaxIterations { get; set; }

        /// <summary>
        /// 轴运动的超时时间（毫秒，默认 30000）
        /// </summary>
        public int MoveTimeoutMilliseconds { get; set; }

        /// <summary>
        /// 识别中心的超时时间（毫秒，默认 10000）
        /// </summary>
        public int RecognitionTimeoutMilliseconds { get; set; }

        public CenterRecognitionParameters RecognitionParameters { get; set; }
    }

    /// <summary>
    /// 逼近对位的结果
    /// </summary>
    public class ApproachAlignmentResult
    {
        public ApproachAlignmentResult()
        {
            FinalErrors = new Dictionary<string, double>();
            FinalAxisPositions = new Dictionary<string, double>();
        }

        /// <summary>
        /// 是否成功（所有轴都在允许误差内）
        /// </summary>
        public bool Succeeded { get; set; }

        /// <summary>
        /// 实际完成的迭代次数
        /// </summary>
        public int CompletedIterations { get; set; }

        /// <summary>
        /// 最终的每轴误差（轴名 -> 误差值）
        /// </summary>
        public Dictionary<string, double> FinalErrors { get; }

        /// <summary>
        /// 最终的轴位置（轴名 -> 位置值，用于调试）
        /// </summary>
        public Dictionary<string, double> FinalAxisPositions { get; }

        /// <summary>
        /// 异常信息（如果失败）
        /// </summary>
        public Exception Exception { get; set; }

        /// <summary>
        /// 获取出错消息
        /// </summary>
        public string Message => Exception?.Message ?? (Succeeded ? "Approach alignment succeeded." : "Approach alignment failed.");
    }

    /// <summary>
    /// 坐标转换结果
    /// </summary>
    public class CoordinateTransformResult
    {
        /// <summary>
        /// 转换后的目标点坐标
        /// </summary>
        public System.Windows.Point TargetPoint { get; set; }

        /// <summary>
        /// 转换是否成功
        /// </summary>
        public bool Succeeded { get; set; }

        /// <summary>
        /// 错误或警告信息
        /// </summary>
        public string Message { get; set; }

        /// <summary>
        /// 转换过程中的异常
        /// </summary>
        public Exception Exception { get; set; }
    }

    #endregion

    #region 接口定义

    /// <summary>
    /// 中心识别器接口：通过图像算法识别目标中心
    /// </summary>
    public interface ICenterRecognizer
    {
        /// <summary>
        /// 识别图像中心点
        /// </summary>
        /// <param name="camera">相机标识（用于指定采图源）</param>
        /// <param name="timeoutMilliseconds">识别超时时间（毫秒）</param>
        /// <param name="cancellationToken">取消令牌</param>
        /// <returns>中心点 (CenterX, CenterY) 或 null 表示识别失败</returns>
        Task<(double CenterX, double CenterY)?> RecognizeCenterAsync(
            CameraType camera,
            int timeoutMilliseconds,
            CancellationToken cancellationToken = default(CancellationToken));

        Task<(double CenterX, double CenterY)?> RecognizeCenterAsync(
            CameraType camera,
            int timeoutMilliseconds,
            CenterRecognitionParameters parameters,
            CancellationToken cancellationToken = default(CancellationToken));
    }

    /// <summary>
    /// 坐标转换器接口：将图像中心点转换为各轴的目标位置
    /// </summary>
    public interface ICoordinateTransformer
    {
        /// <summary>
        /// 将图像中心点坐标转换为轴位置
        /// </summary>
        /// <param name="centerX">图像中心 X 坐标</param>
        /// <param name="centerY">图像中心 Y 坐标</param>
        /// <param name="axes">目标轴列表</param>
        /// <returns>转换结果，包含各轴的目标位置</returns>
        Task<CoordinateTransformResult> TransformAsync(
           System.Windows. Point ruler, System.Windows.Point pixel, string cameraName);
    }

    #endregion
}
