using CCDCount.MODEL.ShuLiModel;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace CCDCount.DLL.Tools
{
    public static class LineScanCameraCalibrator
    {
        /// <summary>
        /// 计算线阵相机X和Y方向的单像素精度
        /// 线阵相机在X方向（像素方向）和Y方向（扫描方向）有不同的缩放系数
        /// </summary>
        /// <param name="knownPairs">已知物理距离的点对集合</param>
        /// <param name="actualDistance">实际物理距离（单位：mm）</param>
        /// <returns>包含X和Y方向单像素精度的结构体</returns>
        public static PixelScale CalculateLineScanPixelScale(List<MaxLengthModel> knownPairs, double actualDistance)
        {
            if (knownPairs == null || knownPairs.Count == 0)
                throw new ArgumentException("至少需要一个点对来进行校准");

            List<double> xScales = new List<double>();
            List<double> yScales = new List<double>();

            foreach (var pair in knownPairs)
            {
                int deltaX = pair.Point2.X - pair.Point1.X;
                int deltaY = pair.Point2.Y - pair.Point1.Y;

                // 计算像素欧几里得距离
                double pixelDistance = Math.Sqrt(deltaX * deltaX + deltaY * deltaY);

                if (pixelDistance == 0)
                    continue; // 避免除零错误

                // 计算每像素的物理距离（缩放因子）
                double scalePerPixel = actualDistance / pixelDistance;

                // 对于线阵相机，我们需要根据X和Y方向的贡献来分解缩放因子
                // X方向精度 = 总缩放因子 * |ΔX| / 像素距离
                // Y方向精度 = 总缩放因子 * |ΔY| / 像素距离
                if (Math.Abs(deltaX) > double.Epsilon)
                {
                    double xScale = scalePerPixel * Math.Abs(deltaX) / pixelDistance;
                    xScales.Add(xScale);
                }

                if (Math.Abs(deltaY) > double.Epsilon)
                {
                    double yScale = scalePerPixel * Math.Abs(deltaY) / pixelDistance;
                    yScales.Add(yScale);
                }
            }

            // 计算平均值作为最终精度
            double avgXScale = xScales.Count > 0 ? xScales.Average() : 1.0;
            double avgYScale = yScales.Count > 0 ? yScales.Average() : 1.0;

            return new PixelScale(avgXScale, avgYScale);
        }

        /// <summary>
        /// 使用更精确的方法计算线阵相机的像素精度
        /// 分别处理纯X方向、纯Y方向和对角线方向的点对
        /// </summary>
        /// <param name="horizontalPairs">纯水平方向点对（Y坐标相同）</param>
        /// <param name="verticalPairs">纯垂直方向点对（X坐标相同）</param>
        /// <param name="diagonalPairs">对角线方向点对</param>
        /// <param name="actualDistance">实际物理距离（单位：mm）</param>
        /// <returns>包含X和Y方向单像素精度的结构体</returns>
        public static PixelScale CalculatePreciseLineScanPixelScale(
            List<MaxLengthModel> horizontalPairs,
            List<MaxLengthModel> verticalPairs,
            List<MaxLengthModel> diagonalPairs,
            double actualDistance)
        {
            double xScale = 1.0, yScale = 1.0;

            // 优先使用纯水平方向点对计算X方向精度
            if (horizontalPairs != null && horizontalPairs.Count > 0)
            {
                var xScales = new List<double>();
                foreach (var pair in horizontalPairs)
                {
                    if (pair.Point1.Y != pair.Point2.Y) continue; // 确保是水平方向

                    int deltaX = pair.Point2.X - pair.Point1.X;
                    if (Math.Abs(deltaX) > 0)
                    {
                        xScales.Add(actualDistance / Math.Abs(deltaX));
                    }
                }
                if (xScales.Count > 0)
                    xScale = xScales.Average();
            }

            // 优先使用纯垂直方向点对计算Y方向精度
            if (verticalPairs != null && verticalPairs.Count > 0)
            {
                var yScales = new List<double>();
                foreach (var pair in verticalPairs)
                {
                    if (pair.Point1.X != pair.Point2.X) continue; // 确保是垂直方向

                    int deltaY = pair.Point2.Y - pair.Point1.Y;
                    if (Math.Abs(deltaY) > 0)
                    {
                        yScales.Add(actualDistance / Math.Abs(deltaY));
                    }
                }
                if (yScales.Count > 0)
                    yScale = yScales.Average();
            }

            // 如果缺少某个方向的纯方向点对，使用对角线点对进行补充
            if (horizontalPairs == null || horizontalPairs.Count == 0)
            {
                // 从对角线点对中估算X方向精度
                if (diagonalPairs != null && diagonalPairs.Count > 0)
                {
                    var xScalesFromDiagonal = new List<double>();
                    foreach (var pair in diagonalPairs)
                    {
                        int deltaX = pair.Point2.X - pair.Point1.X;
                        int deltaY = pair.Point2.Y - pair.Point1.Y;

                        double pixelDistance = Math.Sqrt(deltaX * deltaX + deltaY * deltaY);
                        if (pixelDistance > 0)
                        {
                            double scalePerPixel = actualDistance / pixelDistance;
                            if (Math.Abs(deltaX) > double.Epsilon)
                            {
                                double xScaleFromDiagonal = scalePerPixel * Math.Abs(deltaX) / pixelDistance;
                                xScalesFromDiagonal.Add(xScaleFromDiagonal);
                            }
                        }
                    }
                    if (xScalesFromDiagonal.Count > 0 && xScale == 1.0) // 只在没有纯水平点对时更新
                        xScale = xScalesFromDiagonal.Average();
                }
            }

            if (verticalPairs == null || verticalPairs.Count == 0)
            {
                // 从对角线点对中估算Y方向精度
                if (diagonalPairs != null && diagonalPairs.Count > 0)
                {
                    var yScalesFromDiagonal = new List<double>();
                    foreach (var pair in diagonalPairs)
                    {
                        int deltaX = pair.Point2.X - pair.Point1.X;
                        int deltaY = pair.Point2.Y - pair.Point1.Y;

                        double pixelDistance = Math.Sqrt(deltaX * deltaX + deltaY * deltaY);
                        if (pixelDistance > 0)
                        {
                            double scalePerPixel = actualDistance / pixelDistance;
                            if (Math.Abs(deltaY) > double.Epsilon)
                            {
                                double yScaleFromDiagonal = scalePerPixel * Math.Abs(deltaY) / pixelDistance;
                                yScalesFromDiagonal.Add(yScaleFromDiagonal);
                            }
                        }
                    }
                    if (yScalesFromDiagonal.Count > 0 && yScale == 1.0) // 只在没有纯垂直点对时更新
                        yScale = yScalesFromDiagonal.Average();
                }
            }

            return new PixelScale(xScale, yScale);
        }

        /// <summary>
        /// 使用已知的像素精度计算两点间的物理距离
        /// </summary>
        /// <param name="point1">第一个点</param>
        /// <param name="point2">第二个点</param>
        /// <param name="scale">像素精度</param>
        /// <returns>物理距离（单位：mm）</returns>
        public static double CalculatePhysicalDistance(Point point1, Point point2, PixelScale scale)
        {
            int deltaX = point2.X - point1.X;
            int deltaY = point2.Y - point1.Y;

            // 使用各自的像素精度计算X和Y方向的物理距离
            double physicalDistanceX = Math.Abs(deltaX) * scale.XScale;
            double physicalDistanceY = Math.Abs(deltaY) * scale.YScale;

            // 使用勾股定理计算实际距离
            return Math.Sqrt(
                Math.Pow(physicalDistanceX, 2) +
                Math.Pow(physicalDistanceY, 2)
            );
        }

        /// <summary>
        /// 自动分类点对为水平、垂直和对角线方向
        /// </summary>
        /// <param name="allPairs">所有点对</param>
        /// <param name="horizontalPairs">输出：纯水平方向点对</param>
        /// <param name="verticalPairs">输出：纯垂直方向点对</param>
        /// <param name="diagonalPairs">输出：对角线方向点对</param>
        public static void ClassifyPointPairs(
            List<MaxLengthModel> allPairs,
            out List<MaxLengthModel> horizontalPairs,
            out List<MaxLengthModel> verticalPairs,
            out List<MaxLengthModel> diagonalPairs)
        {
            horizontalPairs = new List<MaxLengthModel>();
            verticalPairs = new List<MaxLengthModel>();
            diagonalPairs = new List<MaxLengthModel>();

            foreach (var pair in allPairs)
            {
                int deltaX = pair.Point2.X - pair.Point1.X;
                int deltaY = pair.Point2.Y - pair.Point1.Y;

                if (deltaY == 0 && Math.Abs(deltaX) > 0)
                {
                    // 水平方向点对（Y坐标相同）
                    horizontalPairs.Add(pair);
                }
                else if (deltaX == 0 && Math.Abs(deltaY) > 0)
                {
                    // 垂直方向点对（X坐标相同）
                    verticalPairs.Add(pair);
                }
                else
                {
                    // 对角线方向点对
                    diagonalPairs.Add(pair);
                }
            }
        }
    }
    /// <summary>
    /// 存储X和Y方向的像素精度
    /// </summary>
    public struct PixelScale
    {
        public double XScale { get; set; } // X方向单像素精度 (mm/pixel)
        public double YScale { get; set; } // Y方向单像素精度 (mm/pixel)

        public PixelScale(double xScale, double yScale)
        {
            XScale = xScale;
            YScale = yScale;
        }

        public override string ToString()
        {
            return $"XScale: {XScale:F6} mm/pixel, YScale: {YScale:F6} mm/pixel";
        }
    }
}
