using JM1.JM1Params;
using MainShell.AlgorithmCalib.Model;
using MainShell.AlgorithmCalib.Service;
using MainShell.AlgorithmCalib.ViewModel;
using MainShell.Common;
using MainShell.Hardware;
using MainShell.Motion;
using MaxwellFramework.Controls;
using MaxwellFramework.Core.Interfaces;
using MwFramework.ManagerService;
using SemiconductorVisionAlgorithm.SemiCalib;
using SemiconductorVisionAlgorithm.SemiParams;
using SemiJM1Vision;
using System;
using System.Collections.Generic;
using System.Data.Common;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Media.Media3D;
using Point = SemiconductorVisionAlgorithm.SemiParams.Point;

namespace MainShell.AlgorithmCalib
{
    public class RotateFormCalibTask : DelegateBase
    {
        public Rectangle1 Rectangle { get; set; }

        private HardwareManager _hardware;
        private RotateCalibParItem _rotateCalibParItem;
        private SemiconductorVisionAlgorithm.SemiParams.Point[,] _initialwsPos;
        private List<SemiconductorVisionAlgorithm.SemiParams.Point[,]> _calibWaferData = new List<SemiconductorVisionAlgorithm.SemiParams.Point[,]>();
        private List<double> _rotatePosList = new List<double>();
        private RotateMatixFormCalibMotionService _motion;
        //private VisionOperation _visionOperation;
        bool _isCancle = false;
        private bool _isReDo = false;
        private bool _isVerify = false;
        private double _initialwsRotate;
        public override bool Check(object state)
        {
            IoC.Get<IProjectManager>().EnablePageAndDisableOther("视觉标定");
            _hardware = IoC.Get<HardwareManager>();
            return true;
        }

        public override void Do(object state)
        {
            try
            {
                // =========== 0. 解析参数 ===========
                var objects = state as object[];
                _rotateCalibParItem = objects[0] as RotateCalibParItem;
                _motion = objects[1] as RotateMatixFormCalibMotionService;
                _isVerify = Convert.ToBoolean(objects[2]);

                double waferStep = _rotateCalibParItem.Wafer_Step;
                double verifyWaferStep = _rotateCalibParItem.VerifyWaferStep;
                _isCancle = false;

                // =========== 1. 初始化视觉 ===========
                //_visionOperation = IoC.Get<VisionOperation>();

                string modelFileName = _rotateCalibParItem.ModelPath;
                string path = AppDomain.CurrentDomain.BaseDirectory + modelFileName;

                if (_isReDo)
                {
                    _isReDo = false;
                }
                else
                {
                    _calibWaferData.Clear();
                    _rotatePosList.Clear();
                }
                if (!_isVerify)
                {
                    RotateCalib(waferStep, path);
                }
                else
                {
                    RotateCalibVerify(verifyWaferStep, path);
                }

            }
            catch (Exception ex)
            {
                MwMessageBox.Show(ex.Message);
                var result = MwMessageBox.Show("是否继续?", "确认",
                    MessageBoxButton.YesNo, MessageBoxImage.Warning);
                if (result == MessageBoxResult.Yes)
                {
                    _isReDo = true;
                    this.Do(state);
                }
                else
                {
                    _isReDo = false;
                }
                return;
            }

            MwMessageBox.Show("校正完成");
        }

        public void RotateCalib(double waferStep, string path)
        {
            // =========== 2. 移动到起始位置，采集初始网格点 ===========
            _initialwsPos = GetInitPoints(waferStep,
                _rotateCalibParItem.X1,
                _rotateCalibParItem.Start_X,
                _rotateCalibParItem.Start_Y,
                path);

            _initialwsRotate = _hardware.Axis_WS_R.State.ActualPos;

            // =========== 3. 计算总旋转步数 ===========
            double rotateStep = _rotateCalibParItem.Rotate_Step;
            //double negLimit = _hardware.Axis_WS_R.State.负限位;
            //double posLimit = _hardware.Axis_WS_R.State.正限位;

            double negLimit = 0;
            double posLimit = 0;

            // 从负限位开始，到正限位结束
            double startAngle = negLimit;
            double range = posLimit - startAngle;
            int totalCount = (int)(range / rotateStep) + 1;
            if (_rotatePosList.Count != totalCount || _calibWaferData.Count != totalCount)
            {
                _calibWaferData.Clear();
                _rotatePosList.Clear();
                int n = _rotateCalibParItem.RowCol;
                for (int i = 0; i < totalCount; i++)
                {
                    _rotatePosList.Add(0);
                    _calibWaferData.Add(new SemiconductorVisionAlgorithm.SemiParams.Point[n, n]);
                }
            }

            // =========== 4. 旋转轴先转到负限位 ===========
            _motion.SafeMove(_hardware.Axis_WS_R, negLimit);

            // =========== 5. 从负限位开始，逐步旋转到正限位，每步采集网格 ===========
            for (int stepIndex = 0; stepIndex < totalCount; stepIndex++)
            {
                double targetRotate = startAngle + rotateStep * stepIndex;

                if (targetRotate > posLimit)
                    break;

                if (_isCancle) return;

                // 旋转到目标角度
                _motion.SafeMove(_hardware.Axis_WS_R, targetRotate);
                _rotatePosList[stepIndex] = _hardware.Axis_WS_R.State.ActualPos;

                int n = _rotateCalibParItem.RowCol;
                var rotateOffset = targetRotate - _initialwsRotate;
                var rotateCenterFilePath = "";
                var resultPts = new SemiconductorVisionAlgorithm.SemiParams.Point[n, n];
                SemiJM1Manager.Instance.RotatePts(rotateCenterFilePath, _initialwsPos, rotateOffset, out resultPts);
                // 采集当前角度下的网格点
                var result_points = GetApproachCenterPoints(resultPts, stepIndex);

                _calibWaferData[stepIndex] = result_points;

            }

            // =========== 6. 融合计算 ===========
            SemiJM1Vision.SemiJM1Manager.Instance.MakeRotateTable(
                _calibWaferData, _rotatePosList, _rotateCalibParItem.Rotate_Step);

            // =========== 7. 保存标定数据 ===========
            string filePath = AppDomain.CurrentDomain.BaseDirectory + @"CalibData";



            JM1Vision.JM1Manager.Instance.Save(filePath);
            MwMessageBox.Show("校正完成");
        }

        public void RotateCalibVerify(double step,  string path)
        {
            List<Point> initVerifyPts=new List<Point>();
            double initWsRotate = _hardware.Axis_WS_R.State.ActualPos;
            double rotateOffset = _rotateCalibParItem.VerifyRotateRange;

            // =========== 2. 获取验证初始点 ===========
            initVerifyPts = GetInitListPoints(step,
                _rotateCalibParItem.VerifyStartX,
                _rotateCalibParItem.VerifyStartY,
                path);

            // =========== 3. 旋转轴转到目标位置 ===========
            double targetRotate = initWsRotate + rotateOffset;
            _motion.SafeMove(_hardware.Axis_WS_R, targetRotate);

            // =========== 4. 调用算法接口进行验证 ===========

            var calPts = new List<Point>();
            var approachPts= new List<Point>();

            SemiJM1Manager.Instance.GetRotateDstPos(initVerifyPts, initWsRotate, rotateOffset, out calPts);

            approachPts = MoveAndGetPts(calPts);

            // =========== 5. 保存验证数据 ===========
            string filePath = AppDomain.CurrentDomain.BaseDirectory + "RotateFormVerify.csv";

            RotateMatixFormCalibFileService.SaveVerifyPointsFile(filePath, calPts, approachPts);
            MwMessageBox.Show("验证完成");
        }

        /// <summary>
        /// 蛇形扫描网格，返回 Point[RowCol, RowCol]
        /// [y, 0]~[y, RowCol-1] = 第 y 行的位置点
        /// </summary>
        private SemiconductorVisionAlgorithm.SemiParams.Point[,] GetInitPoints(
            double waferStep, double x1, double y1, double x2, string path)
        {
            int n = _rotateCalibParItem.RowCol;
            var pointArray = new SemiconductorVisionAlgorithm.SemiParams.Point[n, n];

            _motion.SafeMove(_hardware.Axis_X1, x1);
            _motion.MoveWsAvoidance(x2, y1);

            for (int y = 0; y < n; y++)
            {
                for (int x = 0; x < n; x++)
                {
                    int index = y % 2 == 0 ? x : n - 1 - x;
                    double waferX = index * waferStep + x2;

                    if (_isCancle) return pointArray;

                    _motion.MoveWsAvoidance(waferX, y * waferStep + y1);

                    System.Windows.Point point;
                    //if (!_visionOperation.ApproachPointCircle(
                    //    _hardware.TopCameraExtend, _hardware.Axis_PHS_X2, _hardware.Axis_PHS_Y1,
                    //    path, Rectangle, out point))
                    //{
                    //    Cancel();
                    //}

                    Thread.Sleep(100);

                    var rulerX2 = _hardware.Axis_X2.State.ActualPos;
                    var rulerY1 = _hardware.Axis_Y1.State.ActualPos;

                    //var realPoint = GetRealByRuler(rulerX2, rulerY1);

                    //pointArray[y, x] = realPoint;
                }
            }

            return pointArray;
        }

        /// <summary>
        /// 根据旋转后的拍照位置，蛇形逐个对齐，返回 Point[RowCol, RowCol]
        /// </summary>
        private SemiconductorVisionAlgorithm.SemiParams.Point[,] GetApproachCenterPoints(
            SemiconductorVisionAlgorithm.SemiParams.Point[,] cameraPoints, int stepIndex)
        {
            int n = _rotateCalibParItem.RowCol;
            var resultArray = new SemiconductorVisionAlgorithm.SemiParams.Point[n, n];

            for (int y = 0; y < n; y++)
            {
                for (int x = 0; x < n; x++)
                {
                    // 蛇形索引，与 ApprochWSTable 保持一致
                    int index = y % 2 == 0 ? x : n - 1 - x;

                    if (_isCancle) return resultArray;

                    double px = cameraPoints[y, index].X;
                    double py = cameraPoints[y, index].Y;

                    //var rulerPoint = GetRulerByReal(new Point(px, py));

                    //_motion.MoveWsAvoidance(rulerPoint.X, rulerPoint.Y);

                    System.Windows.Point point;
                    //if (!_visionOperation.ApproachPointCircle(
                    //    _hardware.TopCameraExtend, _hardware.Axis_PHS_X2, _hardware.Axis_PHS_Y1,
                    //    path, Rectangle, out point))
                    //{
                    //    Cancel();
                    //}

                    Thread.Sleep(100);

                    var rulerX2 = _hardware.Axis_X2.State.ActualPos;
                    var rulerY1 = _hardware.Axis_Y1.State.ActualPos;

                    //var realPoint= GetRealByRuler(rulerX2, rulerY1);

                    //// 写入时保持蛇形顺序，与读取顺序一致
                    //resultArray[y, index] = realPoint;
                }
            }

            return resultArray;
        }

        /// <summary>
        /// 蛇形扫描网格，返回List<Point>
        /// </summary>
        private List<SemiconductorVisionAlgorithm.SemiParams.Point> GetInitListPoints(
            double waferStep,  double x2, double y1, string path)
        {
            int n = _rotateCalibParItem.VerifyRowCol;
            _motion.SafeMove(_hardware.Axis_X1, _rotateCalibParItem.X1);
            _motion.MoveWsAvoidance(x2, y1); 

            List<Point> pointArray = new List<Point>();

            for (int y = 0; y < n; y++)
            {
                for (int x = 0; x < n; x++)
                {
                    int index = y % 2 == 0 ? x : n - 1 - x;
                    double waferX = index * waferStep + x2;

                    if (_isCancle) return pointArray;

                    _motion.MoveWsAvoidance(waferX, y * waferStep + y1);

                    System.Windows.Point point;
                    //if (!_visionOperation.ApproachPointCircle(
                    //    _hardware.TopCameraExtend, _hardware.Axis_PHS_X2, _hardware.Axis_PHS_Y1,
                    //    path, Rectangle, out point))
                    //{
                    //    Cancel();
                    //}

                    Thread.Sleep(100);

                    var rulerX2 = _hardware.Axis_X2.State.ActualPos;
                    var rulerY1 = _hardware.Axis_Y1.State.ActualPos;

                    //var realPoint= GetRealByRuler(rulerX2,rulerY1);

                    //pointArray.Add(realPoint);
                }
            }

            return pointArray;
        }

        private List<Point> MoveAndGetPts(List<Point> targetPts)
        {
            var pointArray= new List<Point>();
            foreach(Point pt in targetPts)
            {
                //var rulerPoint = GetRulerByReal(pt);

                //_motion.MoveWsAvoidance(rulerPoint.X, rulerPoint.Y);
                System.Windows.Point point;
                //if (!_visionOperation.ApproachPointCircle(
                //    _hardware.TopCameraExtend, _hardware.Axis_PHS_X2, _hardware.Axis_PHS_Y1,
                //    path, Rectangle, out point))
                //{
                //    Cancel();
                //}

                Thread.Sleep(100);

                var rulerX2 = _hardware.Axis_X2.State.ActualPos;
                var rulerY1 = _hardware.Axis_Y1.State.ActualPos;

                //var realPoint = GetRealByRuler(rulerX2, rulerY1);

                //pointArray.Add(realPoint);
            }
            return pointArray;
        }

        
    }
}
