using JM1.VisionModule;
using MainShell.AlgorithmCalib.Model;
using MainShell.AlgorithmCalib.Service;
using MainShell.AlgorithmCalib.View;
using MainShell.Common;
using MainShell.Common.Display.ViewModel;
using MainShell.Filewritable;
using MainShell.Hardware;
using MaxwellFramework.Core.Interfaces;
using MwFramework.Controls.SystemCalib;
using MwFramework.ManagerService;
using Stylet;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Xml;
using Point = SemiconductorVisionAlgorithm.SemiParams.Point;

namespace MainShell.AlgorithmCalib.ViewModel
{
    public class FusionMenuCalibViewModel : Screen, IPage
    {
        private readonly Dictionary<string, Window> _calibWindows = new Dictionary<string, Window>();
        private List<Point> _calibResultRealPoint = new List<Point>();
        private List<Point> _calibResultAxisPoint = new List<Point>();
        private MotionFusion _motionFusion = new MotionFusion();
        private FusionCalibMotionService _fusionCalibMotionService;
        public string Name { get; set; } = "FusionMenuCalib";
        public string CalibName { get; set; }
        public string FileSaveDir { get; set; }
        private bool _isDataLoaded = false;

        private CameraAxisViewModel _cameraAxisViewModelSevice = new CameraAxisViewModel();
        public CameraAxisViewModel CameraAxisViewModelSevice
        {
            get { return _cameraAxisViewModelSevice; }
            set
            {
                _cameraAxisViewModelSevice = value;
                OnPropertyChanged(nameof(CameraAxisViewModelSevice));
            }
        }
        private ObservableCollection<FusionCalibParItem> _fusionCalibParItem = new ObservableCollection<FusionCalibParItem>();
        public ObservableCollection<FusionCalibParItem> FusionCalibParItem
        {
            get { return _fusionCalibParItem; }
            set
            {
                _fusionCalibParItem = value;
                OnPropertyChanged(nameof(FusionCalibParItem));
            }
        }
        private FusionCalibParItem _selectedCalibPar;
        public FusionCalibParItem SelectedCalibPar
        {
            get { return _selectedCalibPar; }
            set
            {
                _selectedCalibPar = value;
                OnPropertyChanged(nameof(SelectedCalibPar));
            }
        }
        private FusionCalibParItem _inputParam;
        public FusionCalibParItem InputParam
        {
            get { return _inputParam; }
            set { SetAndNotify(ref _inputParam, value); }
        }
        private FusionCalibParItem _resultParam;
        public FusionCalibParItem ResultParam
        {
            get { return _resultParam; }
            set { SetAndNotify(ref _resultParam, value); }
        }
        private List<HardwareDevice> _hardwareDevice;
        public List<HardwareDevice> HardwareDevice
        {
            get { return _hardwareDevice; }
            set
            {
                _hardwareDevice = value;
                NotifyOfPropertyChange();
            }
        }
        private HardwareManager _hardware;
        public HardwareManager Hardware
        {
            get { return _hardware; }
            set
            {
                _hardware = value;
                NotifyOfPropertyChange();
            }
        }
        private bool _isCalibFinished;
        public bool IsCalibFinished
        {
            get { return _isCalibFinished; }
            set { SetAndNotify(ref _isCalibFinished, value); }
        }

        /// <summary>
        /// 无参构造函数
        /// </summary>
        public FusionMenuCalibViewModel()
        {

        }

        /// <summary>
        /// 手动创建时使用的静态工厂方法
        /// </summary>
        /// <param name="cameraName">相机名称，如 "BottomCamera"</param>
        /// <param name="device">对应的硬件设备</param>
        public static FusionMenuCalibViewModel Create(string calibName, string fileSaveName, List<HardwareDevice> device, HardwareManager hardware, FusionCalibMotionService motion)
        {
            var vm = new FusionMenuCalibViewModel();
            vm.Initialize(calibName, fileSaveName, device, hardware, motion);
            return vm;
        }

        protected override void OnViewLoaded()
        {
            base.OnViewLoaded();

            if (_hardware != null)
            {
                _cameraAxisViewModelSevice = new CameraAxisViewModel();
                _cameraAxisViewModelSevice.CameraAxisDevices.HardwareDeviceList = HardwareDevice;
                NotifyOfPropertyChange(nameof(CameraAxisViewModel));
            }
            if (!_isDataLoaded)
            {
                ReadCalibData();
                _isDataLoaded = true;
            }
        }

        private void Initialize(string calibName, string fileSaveName, List<HardwareDevice> device, HardwareManager hardware, FusionCalibMotionService motion)
        {
            CalibName = calibName;
            Hardware = hardware;
            HardwareDevice = device;
            _fusionCalibMotionService = motion;
            FileSaveDir = Path.Combine(Paths.CalibSettingPath, "fusionCalib");
            var paramList = IoC.Get<IParameterManager>() as IParamList;
        }

        public void btnOpenCalibWindow()
        {
            if (SelectedCalibPar == null)
            {
                MwMessageBox.Show("请先选择一组标定数据。", "提示",
                    MessageBoxButton.OK, MessageBoxImage.Information);
                return;
            }
            string cameraId = SelectedCalibPar.Camera_ID;

            // ── 如果已有缓存窗口，直接激活显示 ──
            if (_calibWindows.TryGetValue(cameraId, out var existingWindow))
            {
                if (existingWindow.WindowState == WindowState.Minimized)
                    existingWindow.WindowState = WindowState.Normal;
                existingWindow.Show();
                existingWindow.Activate();
                return;
            }

            var calibVM = CameraFusionPadCalibViewModel.Create("", CalibName, HardwareDevice, SelectedCalibPar, Hardware, _fusionCalibMotionService);
            calibVM.FileSaveDir = this.FileSaveDir;



            // ② 创建视图
            var calibView = new CameraFusionPadCalibView
            {
                DataContext = calibVM,
            };




            // 4. 创建 Window 包裹这个 UserControl
            var window = new Window
            {
                Title = $"融合标定-{cameraId}",
                Width = 1100,
                Height = 750,
                WindowStartupLocation = WindowStartupLocation.CenterOwner,
                Owner = Application.Current.MainWindow,
                ResizeMode = ResizeMode.CanResize,
                Content = calibView
            };

            // ── 拦截关闭：改为隐藏，保留内存状态 ──
            window.Closing += (s, args) =>
            {
                args.Cancel = true;   // 取消真正的关闭
                window.Hide();        // 仅隐藏，VM 和 View 状态全部保留
            };

            // ── 用 Unloaded 代替 Closed 做数据同步 ──
            //    每次隐藏时都把 Service 最新数据写回选中行
            window.IsVisibleChanged += (s, args) =>
            {
                if (!(bool)args.NewValue) // 变为不可见（Hide）
                {
                    SyncCalibResultBack(calibVM);
                }
            };

            // 缓存
            _calibWindows[cameraId] = window;
            window.Show();


            window.Closed += (s, args) =>
            {
                var innerData = calibVM.FusionCalibParItem;
                if (innerData != null)
                {
                    SelectedCalibPar.Index = innerData.Index;
                    SelectedCalibPar.MoveAxisPos = innerData.MoveAxisPos;
                    SelectedCalibPar.ApproachXPos = innerData.ApproachXPos;
                    SelectedCalibPar.ApproachYPos = innerData.ApproachYPos;
                    SelectedCalibPar.StartX = innerData.StartX;
                    SelectedCalibPar.StartY = innerData.StartY;
                    SelectedCalibPar.Step = innerData.Step;
                    SelectedCalibPar.Count = innerData.Count;
                    SelectedCalibPar.RulerPoints = innerData.RulerPoints;
                    SelectedCalibPar.RealPoints = innerData.RealPoints;
                    // 刷新 DataGrid
                    OnPropertyChanged(nameof(FusionCalibParItem));
                }
            };

        }

        /// <summary>
        /// 将内部标定窗口的最新数据同步回外部 DataGrid 选中行
        /// </summary>
        private void SyncCalibResultBack(CameraFusionPadCalibViewModel calibVM)
        {
            var innerData = calibVM.ResultParam;
            if (innerData != null) return;
            var target = FusionCalibParItem.FirstOrDefault(p => p.Camera_ID == calibVM.CameraName);
            if(target == null) return;
            target.Index = innerData.Index;
            target.MoveAxisPos = innerData.MoveAxisPos;
            target.ApproachXPos = innerData.ApproachXPos;
            target.ApproachYPos = innerData.ApproachYPos;
            target.StartX = innerData.StartX;
            target.StartY = innerData.StartY;
            target.Step = innerData.Step;
            target.Count = innerData.Count;
            target.RulerPoints = innerData.RulerPoints;
            target.RealPoints = innerData.RealPoints;
            // 刷新 DataGrid
            OnPropertyChanged(nameof(FusionCalibParItem));
        }

        public void btnReadCalibData()
        {
            var result = MwMessageBox.Show($"确认读取本地标定数据?", "确认读取", MessageBoxButton.YesNo, MessageBoxImage.Warning);
            if (result == MessageBoxResult.Yes)
            {
                if (!ReadCalibData())
                {
                    MwMessageBox.Show("读取本地标定数据失败！", "提示", MessageBoxButton.OK, MessageBoxImage.Error);
                }
            }
        }
        public bool ReadCalibData()
        {
            try
            {
                var paramList = IoC.Get<IParameterManager>() as IParamList;

                //FusionCalibParItem.CalibParList = new ObservableCollection<FusionSysDataItem>();

                for (int i = 0; i < 4; i++)
                {
                    var filePath = Path.Combine(FileSaveDir, $"Fusion_Time{i + 1}.xml");
                    var pointsFilePath = Path.Combine(FileSaveDir, $"Fusion_Time{i + 1}.txt");

                    bool hasXml = File.Exists(filePath);
                    bool hasTxt = File.Exists(pointsFilePath);

                    double moveAxisPos = 0;
                    double approachXPos = 0;
                    double approachYPos = 0;
                    double startX = 0;
                    double startY = 0;
                    double step = 0;
                    int count = 0;
                    List<Point> rulerPoints = new List<Point>();
                    List<Point> realPoints = new List<Point>();

                    // ① 有 XML → 读取参数
                    if (hasXml)
                    {
                        //var uiData = UIDataManager.Instance.GetUIData<FusionCalibParItem>(paramList);
                        //uiData.Read(filePath);
                        //var xmlData=XmlReader(filePath);

                        //if (xmlData.Datas != null && xmlData.Datas.Count > 0)
                        //{
                        //    var item = xmlData.Datas[0]; // 每个文件只有一组数据
                        //    index=item.Index;
                        //    moveAxisPos = item.MoveAxisPos;
                        //    approachXPos = item.ApproachXPos;
                        //    approachYPos = item.ApproachYPos;
                        //    startX = item.StartX;
                        //    startY = item.StartY;
                        //    step = item.Step;
                        //    count = item.Count;
                        //}
                    }

                    // ② 有 TXT → 读取标定点位
                    if (hasTxt)
                    {
                        MotionCalibFileService.ReadCalibPointsFile(
                            pointsFilePath, out realPoints, out rulerPoints);

                        rulerPoints = rulerPoints ?? new List<Point>();
                        realPoints = realPoints ?? new List<Point>();
                    }

                    // ③ 无论什么情况，都加到列表（保证 5 组都在）
                    var par = new FusionCalibParItem
                    {
                        Index = i + 1,
                        Camera_ID = "Fusion_Time" + (i + 1),
                        MoveAxisPos = moveAxisPos,
                        ApproachXPos = approachXPos,
                        ApproachYPos = approachYPos,
                        StartX = startX,
                        StartY = startY,
                        Step = step,
                        Count = count,
                        RulerPoints = rulerPoints,
                        RealPoints = realPoints,
                    };
                    FusionCalibParItem.Add(par);
                }

                return true;
            }
            catch
            {
                return false;
            }
        }

        public void btnApplyCalibData()
        {
            //if (FusionCalibParItem.CalibParList.Count != 5)
            //{
            //    MwMessageBox.Show("标定数据不足，请完成全部标定！", "提示", MessageBoxButton.OK, MessageBoxImage.Error);
            //    return;
            //}
            //var result = MwMessageBox.Show($"确认应用标定数据?", "确认应用", MessageBoxButton.YesNo, MessageBoxImage.Warning);
            //if (result == MessageBoxResult.Yes)
            //{
            //    if (true) //
            //    {

            //        MwMessageBox.Show("应用标定数据成功！", "提示", MessageBoxButton.OK, MessageBoxImage.Information);
            //    }
            //}
        }

        public void ApplayCalibData()
        {
            //List<string> cameraIdList = new List<string>();
            //for (int i = 0; i < 5; i++)
            //{
            //    var resultPointsList = FusionCalibParItem.CalibParList[i];
            //    _motionFusion.Set(i, resultPointsList.ResultRealPoints, resultPointsList.ResultAxisPoints);
            //    cameraIdList.Add(resultPointsList.CameraId);
            //}
            //_motionFusion.AutoSelectPt(cameraIdList[0], cameraIdList[1], cameraIdList[2], cameraIdList[3], out _calibResultRealPoint, out _calibResultAxisPoint);

            //MwAlgorithmHelper.Instance.RulerToRealMaritex("topCameraPad", _calibResultAxisPoint, _calibResultRealPoint, 1, 1, 1, 1, UIDataManager.CalibDataDir);
        }

        public void XmlReader(string xmlFilePath)
        {

        }
    }
}
