using MainShell.AlgorithmCalib.Model;
using MainShell.AlgorithmCalib.Service;
using MainShell.Common;
using MainShell.Common.Display.ViewModel;
using MainShell.Hardware;
using MainShell.Motion;
using MaxwellFramework.Core.Interfaces;
using MwFramework.Controls.ControlCanvas.Model;
using MwFramework.ManagerService;
using SemiconductorVisionAlgorithm.SemiParams;
using Stylet;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using SemiPoint = SemiconductorVisionAlgorithm.SemiParams.Point;

namespace MainShell.AlgorithmCalib.ViewModel
{
    /// <summary>
    /// 融合对位验证VM
    /// 3步对位流程：抓Pad点 → Die网格飞拍 → 选择Die点对位Pad
    /// </summary>
    public class FusionAlignVerifyViewModel : Screen, IPage
    {
        private readonly FusionCalibMotionService _motionService;
        private readonly HardwareManager _hardware;
        private FusionAlignProcessor _alignProcessor;
        private CancellationTokenSource _cts;
        private ApproachAlignmentService _approachAlignmentService;

        public string Name { get; set; } = "FusionAlignVerify";
        public string CalibName { get; set; } = "整体对位验证";

        #region 属性

        private FusionCalibModuleItem _moduleItem = new FusionCalibModuleItem();
        public FusionCalibModuleItem ModuleItem
        {
            get => _moduleItem;
            set => SetAndNotify(ref _moduleItem, value);
        }

        // DieFusionCalibView 绑定
        public FusionCalibModuleItem WsFusionCalibParItem
        {
            get => _moduleItem;
            set { _moduleItem = value; NotifyOfPropertyChange(nameof(WsFusionCalibParItem)); }
        }

        // PadFusionCalibView 绑定
        public FusionCalibModuleItem FusionCalibParItem
        {
            get => _moduleItem;
            set { _moduleItem = value; NotifyOfPropertyChange(nameof(FusionCalibParItem)); }
        }

        private CameraAxisViewModel _cameraAxisViewModelSevice;
        public CameraAxisViewModel CameraAxisViewModelSevice
        {
            get => _cameraAxisViewModelSevice;
            set => SetAndNotify(ref _cameraAxisViewModelSevice, value);
        }

        private DelegateBase _motion = new DelegateBase();
        public DelegateBase Motion
        {
            get => _motion;
            set => SetAndNotify(ref _motion, value);
        }

        private string _progressMessage = "";
        public string ProgressMessage
        {
            get => _progressMessage;
            set => SetAndNotify(ref _progressMessage, value);
        }

        private bool _isRunning;
        public bool IsRunning
        {
            get => _isRunning;
            set => SetAndNotify(ref _isRunning, value);
        }

        private string _alignResultText = "";
        public string AlignResultText
        {
            get => _alignResultText;
            set => SetAndNotify(ref _alignResultText, value);
        }

        // ===== 步骤1：Pad捕获 =====
        private double _padCapturedX;
        public double PadCapturedX
        {
            get => _padCapturedX;
            set => SetAndNotify(ref _padCapturedX, value);
        }

        private double _padCapturedY;
        public double PadCapturedY
        {
            get => _padCapturedY;
            set => SetAndNotify(ref _padCapturedY, value);
        }

        // ===== 步骤2：Die网格飞拍 =====
        private double _dieFirstX;
        public double DieFirstX
        {
            get => _dieFirstX;
            set => SetAndNotify(ref _dieFirstX, value);
        }

        private double _dieFirstY;
        public double DieFirstY
        {
            get => _dieFirstY;
            set => SetAndNotify(ref _dieFirstY, value);
        }

        private int _flyScanXCount = 3;
        public int FlyScanXCount
        {
            get => _flyScanXCount;
            set => SetAndNotify(ref _flyScanXCount, value);
        }

        private int _flyScanYCount = 3;
        public int FlyScanYCount
        {
            get => _flyScanYCount;
            set => SetAndNotify(ref _flyScanYCount, value);
        }

        private double _flyScanStep = 1.0;
        public double FlyScanStep
        {
            get => _flyScanStep;
            set => SetAndNotify(ref _flyScanStep, value);
        }

        private string _flyScanResultText = "";
        public string FlyScanResultText
        {
            get => _flyScanResultText;
            set => SetAndNotify(ref _flyScanResultText, value);
        }

        private ObservableCollection<DieGridPointDisplay> _displayDieGridPoints = new ObservableCollection<DieGridPointDisplay>();
        public ObservableCollection<DieGridPointDisplay> DisplayDieGridPoints
        {
            get => _displayDieGridPoints;
            set => SetAndNotify(ref _displayDieGridPoints, value);
        }

        // ===== 步骤3：对位选择 =====
        private int _selectedRow;
        public int SelectedRow
        {
            get => _selectedRow;
            set => SetAndNotify(ref _selectedRow, value);
        }

        private int _selectedCol;
        public int SelectedCol
        {
            get => _selectedCol;
            set => SetAndNotify(ref _selectedCol, value);
        }

        #endregion

        #region 构造

        public FusionAlignVerifyViewModel() { }

        //public FusionAlignVerifyViewModel(List<HardwareDevice> device,
        //    HardwareManager hardware,
        //    FusionCalibMotionService motion)
        //{
        //    _approachAlignmentService = IoC.Get<ApproachAlignmentService>();
        //    _cameraAxisViewModelSevice = IoC.Get<CameraAxisViewModel>();
        //    _cameraAxisViewModelSevice.CameraAxisDevices.HardwareDeviceList = device;
        //    _hardware = hardware;
        //    _motionService = motion;
        //    _alignProcessor= new FusionAlignProcessor(motion, hardware, ModuleItem, GetRoiRect);
        //    _alignProcessor.ProgressChanged += (s, e) =>
        //    {
        //        Application.Current.Dispatcher.Invoke(() =>
        //        {
        //            ProgressMessage = e.Message;
        //        });
        //    };
        //}

        public FusionAlignVerifyViewModel(HardwareManager hardware, FusionCalibMotionService motion)
        {
            _hardware = hardware;
            _motionService = motion;
            _approachAlignmentService = IoC.Get<ApproachAlignmentService>();

        }

        public static FusionAlignVerifyViewModel Create(
            List<HardwareDevice> device,
            HardwareManager hardware,
            FusionCalibMotionService motion)
        {
            var vm = new FusionAlignVerifyViewModel(hardware, motion);
            vm.CameraAxisViewModelSevice = IoC.Get<CameraAxisViewModel>();
            vm.CameraAxisViewModelSevice.CameraAxisDevices.HardwareDeviceList = device;
            vm._alignProcessor = new FusionAlignProcessor(motion, hardware, vm.ModuleItem, vm.GetRoiRect);
            vm._alignProcessor.ProgressChanged += (s, e) =>
            {
                Application.Current.Dispatcher.Invoke(() =>
                {
                    vm.ProgressMessage = e.Message;
                });
            };
            return vm;
        }

        #endregion

        #region 按钮操作

        /// <summary>
        /// 步骤1：抓Pad点
        /// 框选ROI区域，识别Pad目标点，记录pad坐标(X1,Y2)
        /// </summary>
        public void btnCapturePad()
        {
            if (MwMessageBox.Show("是否在当前位置框选ROI抓Pad点?", "确认", MessageBoxButton.YesNo) != MessageBoxResult.Yes)
                return;

            _cts = new CancellationTokenSource();
            Task.Run(async () =>
            {
                try
                {
                    IsRunning = true;
                    await _alignProcessor.CapturePadPointAsync(_cts.Token);

                    Application.Current.Dispatcher.Invoke(() =>
                    {
                        PadCapturedX = _moduleItem.PadRulerX;
                        PadCapturedY = _moduleItem.PadRulerY;
                    });

                    MwMessageBox.Show($"抓Pad点完成\nPad: ({PadCapturedX:F4}, {PadCapturedY:F4})");
                }
                catch (OperationCanceledException) { MwMessageBox.Show("已取消"); }
                catch (Exception ex) { MwMessageBox.Show($"抓Pad点失败：{ex.Message}"); }
                finally { IsRunning = false; }
            });
        }

        /// <summary>
        /// 步骤2a：抓Die首点
        /// 框选ROI区域，识别Die首点坐标(X2,Y1)
        /// </summary>
        public void btnCaptureDieFirst()
        {
            if (MwMessageBox.Show("是否在当前位置框选ROI抓Die首点?", "确认", MessageBoxButton.YesNo) != MessageBoxResult.Yes)
                return;

            _cts = new CancellationTokenSource();
            Task.Run(async () =>
            {
                try
                {
                    IsRunning = true;
                    await _alignProcessor.CaptureDieFirstPointAsync(_cts.Token);

                    Application.Current.Dispatcher.Invoke(() =>
                    {
                        DieFirstX = _moduleItem.DieRulerX;
                        DieFirstY = _moduleItem.DieRulerY;
                    });

                    MwMessageBox.Show($"抓Die首点完成\nDie: ({DieFirstX:F4}, {DieFirstY:F4})");
                }
                catch (OperationCanceledException) { MwMessageBox.Show("已取消"); }
                catch (Exception ex) { MwMessageBox.Show($"抓Die首点失败：{ex.Message}"); }
                finally { IsRunning = false; }
            });
        }

        /// <summary>
        /// 步骤2b：执行Die网格飞拍
        /// 以Die首点为起点，按step和count执行蛇形网格飞拍
        /// </summary>
        public void btnStartFlyScan()
        {
            if (FlyScanXCount <= 0 || FlyScanYCount <= 0)
            {
                MwMessageBox.Show("请设置有效的X Count和Y Count（需大于0）");
                return;
            }
            if (FlyScanStep <= 0)
            {
                MwMessageBox.Show("请设置有效的Step（需大于0）");
                return;
            }

            if (MwMessageBox.Show($"是否以首点({DieFirstX:F4}, {DieFirstY:F4})为起点开始飞拍？\n" +
                                  $"网格：{FlyScanXCount}×{FlyScanYCount}，步长：{FlyScanStep}mm",
                                  "确认", MessageBoxButton.YesNo) != MessageBoxResult.Yes)
                return;

            // 将飞拍参数同步到processor
            _alignProcessor.SetFlyScanParams(DieFirstX, DieFirstY, FlyScanXCount, FlyScanYCount, FlyScanStep);

            _cts = new CancellationTokenSource();
            Task.Run(async () =>
            {
                try
                {
                    IsRunning = true;
                    await _alignProcessor.ExecuteDieGridFlyScanAsync(_cts.Token);

                    Application.Current.Dispatcher.Invoke(() =>
                    {
                        FlyScanResultText = $"飞拍完成，共获取 {_moduleItem.DieGridPoints.Count} 个Die点";
                        DisplayDieGridPoints.Clear();
                        for (int i = 0; i < _moduleItem.DieGridPoints.Count; i++)
                        {
                            var pt = _moduleItem.DieGridPoints[i];
                            DisplayDieGridPoints.Add(new DieGridPointDisplay
                            {
                                Row = pt.Item1,
                                Col = pt.Item2,
                                X = pt.Item3.X,
                                Y = pt.Item3.Y
                            });
                        }
                    });

                    MwMessageBox.Show($"飞拍完成，共获取 {_moduleItem.DieGridPoints.Count} 个Die点");
                }
                catch (OperationCanceledException) { MwMessageBox.Show("已取消"); }
                catch (Exception ex) { MwMessageBox.Show($"飞拍失败：{ex.Message}"); }
                finally { IsRunning = false; }
            });
        }

        /// <summary>
        /// 步骤3：执行对位
        /// 用户选择网格中的一个Die点，与Pad点执行对位
        /// </summary>
        public void btnExecuteAlign()
        {
            if (_moduleItem.DieGridPoints == null || _moduleItem.DieGridPoints.Count == 0)
            {
                MwMessageBox.Show("请先执行Die网格飞拍");
                return;
            }

            if (SelectedRow < 0 || SelectedCol < 0)
            {
                MwMessageBox.Show("请输入有效的行列号（从0开始）");
                return;
            }

            bool found = _moduleItem.DieGridPoints.Any(p => p.Item1 == SelectedRow && p.Item2 == SelectedCol);
            if (!found)
            {
                MwMessageBox.Show($"未找到第{SelectedRow}行第{SelectedCol}列的Die点，请检查输入");
                return;
            }

            if (MwMessageBox.Show($"是否将Die[{SelectedRow},{SelectedCol}]与Pad({PadCapturedX:F4}, {PadCapturedY:F4})对位?",
                                  "确认", MessageBoxButton.YesNo) != MessageBoxResult.Yes)
                return;

            _cts = new CancellationTokenSource();
            Task.Run(async () =>
            {
                try
                {
                    IsRunning = true;
                    await _alignProcessor.ExecuteAlignAsync(_cts.Token, SelectedRow, SelectedCol);

                    Application.Current.Dispatcher.Invoke(() =>
                    {
                        AlignResultText = $"选择Die点: [{SelectedRow},{SelectedCol}]\n" +
                                         $"Die坐标(X2,Y1): ({_moduleItem.DieRealX:F4}, {_moduleItem.DieRealY:F4})\n" +
                                         $"Pad坐标(X1,Y2): ({_moduleItem.PadRealX:F4}, {_moduleItem.PadRealY:F4})\n" +
                                         $"对齐后 X1: {_moduleItem.AlignResultX:F4}\n" +
                                         $"对齐后 Y1: {_moduleItem.AlignResultY:F4}\n" +
                                         $"X2补偿: {_moduleItem.AlignResultX2:F4}";
                    });

                    MwMessageBox.Show("对位完成！");
                }
                catch (OperationCanceledException) { MwMessageBox.Show("已取消"); }
                catch (Exception ex) { MwMessageBox.Show($"对位失败：{ex.Message}"); }
                finally { IsRunning = false; }
            });
        }

        private Rectangle1 GetRoiRect()
        {
            try
            {
                var region = CameraAxisViewModelSevice?.Regions;
                if (region?.Count > 0 && region[0].Region is RectRegion rect)
                {
                    return new Rectangle1
                    {
                        Start_X = rect.CenterPoint.Y - rect.Height / 2,
                        Start_Y = rect.CenterPoint.X - rect.Width / 2,
                        End_X = rect.CenterPoint.Y + rect.Height / 2,
                        End_Y = rect.CenterPoint.X + rect.Width / 2
                    };
                }
            }
            catch { }
            return null;
        }

        /// <summary>
        /// 停止
        /// </summary>
        public void btnStopAlign()
        {
            _cts?.Cancel();
        }

        #endregion
    }

    /// <summary>
    /// Die网格点显示模型（用于DataGrid绑定）
    /// </summary>
    public class DieGridPointDisplay
    {
        public int Row { get; set; }
        public int Col { get; set; }
        public double X { get; set; }
        public double Y { get; set; }
    }
}