using System;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Input;
using System.Windows.Threading;
using DeviceCommand.Devices;
using Logger;
using Prism.Ioc;
using UIShare.GlobalVariable;
using UIShare.ViewModelBase;

namespace BenchMovementModule.ViewModels
{
    public class BenchMovementViewModel : NavigateViewModelBase, IRegionMemberLifetime, IDisposable
    {
        #region 属性

        public bool KeepAlive => true;

        // ===== GantryControlTcp 实例（从 DeviceManager 获取）=====
        private GantryControlTcp? _gantry;
        private DeviceManager? _deviceManager;
        private readonly GlobalInfo _globalInfo;

        // ===== 连接状态 =====
        private bool _isConnected;
        public bool IsConnected
        {
            get => _isConnected;
            set => SetProperty(ref _isConnected, value);
        }

        private string _connectionStatus = "未连接";
        public string ConnectionStatus
        {
            get => _connectionStatus;
            set => SetProperty(ref _connectionStatus, value);
        }

        // ===== 6轴绝对位置显示（相对原点的实时位置，只读）=====
        private int _absPos1;
        public int AbsPos1 { get => _absPos1; set => SetProperty(ref _absPos1, value); }

        private int _absPos2;
        public int AbsPos2 { get => _absPos2; set => SetProperty(ref _absPos2, value); }

        private int _absPos3;
        public int AbsPos3 { get => _absPos3; set => SetProperty(ref _absPos3, value); }

        private int _absPos4;
        public int AbsPos4 { get => _absPos4; set => SetProperty(ref _absPos4, value); }

        private int _absPos5;
        public int AbsPos5 { get => _absPos5; set => SetProperty(ref _absPos5, value); }

        private int _absPos6;
        public int AbsPos6 { get => _absPos6; set => SetProperty(ref _absPos6, value); }

        // ===== 寸动目标位置 =====
        private int _targetX;
        public int TargetX { get => _targetX; set => SetProperty(ref _targetX, value); }

        private int _targetY;
        public int TargetY { get => _targetY; set => SetProperty(ref _targetY, value); }

        private int _targetZ;
        public int TargetZ { get => _targetZ; set => SetProperty(ref _targetZ, value); }

        // ===== 扫描参数 =====
        private int _scanStepX = 1000;
        public int ScanStepX { get => _scanStepX; set => SetProperty(ref _scanStepX, value); }

        private int _scanStartX;
        public int ScanStartX { get => _scanStartX; set => SetProperty(ref _scanStartX, value); }

        private int _scanEndX = 50000;
        public int ScanEndX { get => _scanEndX; set => SetProperty(ref _scanEndX, value); }

        private int _scanStepY = 1000;
        public int ScanStepY { get => _scanStepY; set => SetProperty(ref _scanStepY, value); }

        private int _scanStartY;
        public int ScanStartY { get => _scanStartY; set => SetProperty(ref _scanStartY, value); }

        private int _scanEndY = 50000;
        public int ScanEndY { get => _scanEndY; set => SetProperty(ref _scanEndY, value); }

        private int _scanStepZ = 100;
        public int ScanStepZ { get => _scanStepZ; set => SetProperty(ref _scanStepZ, value); }

        private int _scanStartZ;
        public int ScanStartZ { get => _scanStartZ; set => SetProperty(ref _scanStartZ, value); }

        private int _scanEndZ = 20000;
        public int ScanEndZ { get => _scanEndZ; set => SetProperty(ref _scanEndZ, value); }

        // ===== 速度设定（脉冲）=====
        private int _speedX = 5000;
        public int SpeedX { get => _speedX; set => SetProperty(ref _speedX, value); }

        private int _speedY = 5000;
        public int SpeedY { get => _speedY; set => SetProperty(ref _speedY, value); }

        private int _speedZ = 2000;
        public int SpeedZ { get => _speedZ; set => SetProperty(ref _speedZ, value); }

        private int _homeSpeed = 3000;
        public int HomeSpeed { get => _homeSpeed; set => SetProperty(ref _homeSpeed, value); }

        // ===== 零点设定 =====
        private int _homeX;
        public int HomeX { get => _homeX; set => SetProperty(ref _homeX, value); }

        private int _homeY;
        public int HomeY { get => _homeY; set => SetProperty(ref _homeY, value); }

        private int _homeZ;
        public int HomeZ { get => _homeZ; set => SetProperty(ref _homeZ, value); }

        #endregion

        #region 命令
        public ICommand ConnectCommand { get; }
        public ICommand DisconnectCommand { get; }
        public ICommand MoveXCommand { get; }
        public ICommand MoveYCommand { get; }
        public ICommand MoveZCommand { get; }
        public ICommand MoveAllCommand { get; }
        public ICommand GoHomeCommand { get; }
        public ICommand EmergencyStopCommand { get; }
        public ICommand StopXCommand { get; }
        public ICommand StopYCommand { get; }
        public ICommand StopZCommand { get; }
        public ICommand SetSpeedCommand { get; }
        public ICommand SetHomeCommand { get; }
        public ICommand ReadStatusCommand { get; }
        #endregion

        #region 私有字段
        private readonly DispatcherTimer _pollTimer;
        private bool _isInitiated = false;
        #endregion

        public BenchMovementViewModel(IContainerProvider containerProvider) : base(containerProvider)
        {
            _globalInfo = containerProvider.Resolve<GlobalInfo>();
            ConnectCommand = new DelegateCommand(OnConnect);
            DisconnectCommand = new DelegateCommand(OnDisconnect);
            MoveXCommand = new DelegateCommand(OnMoveX);
            MoveYCommand = new DelegateCommand(OnMoveY);
            MoveZCommand = new DelegateCommand(OnMoveZ);
            MoveAllCommand = new DelegateCommand(OnMoveAll);
            GoHomeCommand = new DelegateCommand(OnGoHome);
            EmergencyStopCommand = new DelegateCommand(OnEmergencyStop);
            StopXCommand = new DelegateCommand(OnStopX);
            StopYCommand = new DelegateCommand(OnStopY);
            StopZCommand = new DelegateCommand(OnStopZ);
            SetSpeedCommand = new DelegateCommand(OnSetSpeed);
            SetHomeCommand = new DelegateCommand(OnSetHome);
            ReadStatusCommand = new DelegateCommand(OnReadStatus);

            // 位置轮询定时器（500ms）
            _pollTimer = new DispatcherTimer(DispatcherPriority.Background)
            {
                Interval = TimeSpan.FromMilliseconds(500)
            };
            _pollTimer.Tick += OnPollTick;
        }

        #region 命令处理

        private async void OnConnect()
        {
            if (_gantry == null) return;
            try
            {
                ConnectionStatus = "连接中...";
                bool ok = await _gantry.ConnectAsync();
                if (ok)
                {
                    IsConnected = true;
                    ConnectionStatus = "已连接";
                    _pollTimer.Start();
                    await ReadDeviceParametersAsync();
                    LoggerHelper.Info("[BenchMovement] 台架连接成功");
                }
                else
                {
                    ConnectionStatus = "连接失败";
                }
            }
            catch (Exception ex)
            {
                LoggerHelper.Error($"[BenchMovement] 连接失败: {ex.Message}");
                ConnectionStatus = $"连接失败: {ex.Message}";
            }
            UpdateConnectionStatus();
        }

        private void OnDisconnect()
        {
            if (_gantry == null) return;
            try
            {
                _pollTimer.Stop();
                _gantry.Close();
                IsConnected = false;
                ConnectionStatus = "未连接";
                LoggerHelper.Info("[BenchMovement] 台架已断开");
            }
            catch (Exception ex)
            {
                LoggerHelper.Error($"[BenchMovement] 断开失败: {ex.Message}");
            }
            UpdateConnectionStatus();
        }

        private async void OnMoveX()
        {
            if (!EnsureConnected()) return;
            try
            {
                await _gantry!.SetAxisTargetPositionAsync(1, TargetX);
                await _gantry.StartSingleAxisAsync(1);
                LoggerHelper.Info($"[BenchMovement] X轴移动到 {TargetX}");
            }
            catch (Exception ex)
            {
                LoggerHelper.Error($"[BenchMovement] X轴移动失败: {ex.Message}");
                ShowErrorMessageBox($"X轴移动失败: {ex.Message}", () => { });
            }
        }

        private async void OnMoveY()
        {
            if (!EnsureConnected()) return;
            try
            {
                await _gantry!.SetAxisTargetPositionAsync(2, TargetY);
                await _gantry.StartSingleAxisAsync(2);
                LoggerHelper.Info($"[BenchMovement] Y轴移动到 {TargetY}");
            }
            catch (Exception ex)
            {
                LoggerHelper.Error($"[BenchMovement] Y轴移动失败: {ex.Message}");
                ShowErrorMessageBox($"Y轴移动失败: {ex.Message}", () => { });
            }
        }

        private async void OnMoveZ()
        {
            if (!EnsureConnected()) return;
            try
            {
                await _gantry!.SetAxisTargetPositionAsync(3, TargetZ);
                await _gantry.StartSingleAxisAsync(3);
                LoggerHelper.Info($"[BenchMovement] Z轴移动到 {TargetZ}");
            }
            catch (Exception ex)
            {
                LoggerHelper.Error($"[BenchMovement] Z轴移动失败: {ex.Message}");
                ShowErrorMessageBox($"Z轴移动失败: {ex.Message}", () => { });
            }
        }

        private async void OnMoveAll()
        {
            if (!EnsureConnected()) return;
            try
            {
                await _gantry!.SetAxisTargetPositionAsync(1, TargetX);
                await _gantry.SetAxisTargetPositionAsync(2, TargetY);
                await _gantry.SetAxisTargetPositionAsync(3, TargetZ);
                await _gantry.StartAllAxesAsync();
                LoggerHelper.Info($"[BenchMovement] 三轴同时移动: X={TargetX}, Y={TargetY}, Z={TargetZ}");
            }
            catch (Exception ex)
            {
                LoggerHelper.Error($"[BenchMovement] 三轴移动失败: {ex.Message}");
                ShowErrorMessageBox($"三轴移动失败: {ex.Message}", () => { });
            }
        }

        private async void OnGoHome()
        {
            if (!EnsureConnected()) return;
            try
            {
                await _gantry!.HomeAsync();
                LoggerHelper.Info("[BenchMovement] 回原点已触发");
            }
            catch (Exception ex)
            {
                LoggerHelper.Error($"[BenchMovement] 回原点失败: {ex.Message}");
                ShowErrorMessageBox($"回原点失败: {ex.Message}", () => { });
            }
        }

        private async void OnEmergencyStop()
        {
            if (!EnsureConnected()) return;
            try
            {
                await _gantry!.SetEStopStateAsync(true);
                LoggerHelper.Info("[BenchMovement] 急停已触发");
            }
            catch (Exception ex)
            {
                LoggerHelper.Error($"[BenchMovement] 急停失败: {ex.Message}");
            }
        }

        private async void OnStopX()
        {
            if (!EnsureConnected()) return;
            try
            {
                await _gantry!.SetStopStateAsync(1, true);
                await Task.Delay(100);
                await _gantry.SetStopStateAsync(1, false);
            }
            catch (Exception ex)
            {
                LoggerHelper.Error($"[BenchMovement] X轴停止失败: {ex.Message}");
            }
        }

        private async void OnStopY()
        {
            if (!EnsureConnected()) return;
            try
            {
                await _gantry!.SetStopStateAsync(2, true);
                await Task.Delay(100);
                await _gantry.SetStopStateAsync(2, false);
            }
            catch (Exception ex)
            {
                LoggerHelper.Error($"[BenchMovement] Y轴停止失败: {ex.Message}");
            }
        }

        private async void OnStopZ()
        {
            if (!EnsureConnected()) return;
            try
            {
                await _gantry!.SetStopStateAsync(3, true);
                await Task.Delay(100);
                await _gantry.SetStopStateAsync(3, false);
            }
            catch (Exception ex)
            {
                LoggerHelper.Error($"[BenchMovement] Z轴停止失败: {ex.Message}");
            }
        }

        private async void OnSetSpeed()
        {
            if (!EnsureConnected()) return;
            try
            {
                await _gantry!.SetAxisSpeedAsync(1, SpeedX);
                await _gantry.SetAxisSpeedAsync(2, SpeedY);
                await _gantry.SetAxisSpeedAsync(3, SpeedZ);
                await _gantry.SetHomePositionSpeedAsync(HomeSpeed);
                LoggerHelper.Info($"[BenchMovement] 速度设定完成: X={SpeedX}, Y={SpeedY}, Z={SpeedZ}, 回零={HomeSpeed}");
            }
            catch (Exception ex)
            {
                LoggerHelper.Error($"[BenchMovement] 速度设定失败: {ex.Message}");
                ShowErrorMessageBox($"速度设定失败: {ex.Message}", () => { });
            }
        }

        private async void OnSetHome()
        {
            if (!EnsureConnected()) return;
            try
            {
                await _gantry!.SetHomePositionAsync(HomeX, HomeY, HomeZ);
                LoggerHelper.Info($"[BenchMovement] 零点设定完成: X={HomeX}, Y={HomeY}, Z={HomeZ}");
            }
            catch (Exception ex)
            {
                LoggerHelper.Error($"[BenchMovement] 零点设定失败: {ex.Message}");
                ShowErrorMessageBox($"零点设定失败: {ex.Message}", () => { });
            }
        }

        private async void OnReadStatus()
        {
            await ReadDeviceParametersAsync();
        }

        #endregion

        #region 辅助方法

        private bool EnsureConnected()
        {
            if (_gantry == null || !_gantry.IsConnected)
            {
                ShowErrorMessageBox("设备未连接，请先连接台架", () => { });
                return false;
            }
            return true;
        }

        private void UpdateConnectionStatus()
        {
            IsConnected = _gantry?.IsConnected ?? false;
            ConnectionStatus = IsConnected ? "已连接" : "未连接";
        }

        private async Task ReadDeviceParametersAsync()
        {
            if (_gantry == null || !_gantry.IsConnected) return;
            try
            {
                var (x, y, z) = await _gantry.GetHomePositionAsync();
                HomeX = x; HomeY = y; HomeZ = z;

                SpeedX = await _gantry.GetAxisSpeedAsync(1);
                SpeedY = await _gantry.GetAxisSpeedAsync(2);
                SpeedZ = await _gantry.GetAxisSpeedAsync(3);
                HomeSpeed = await _gantry.GetHomePositionSpeedAsync();

                // 读取 6 轴绝对位置
                var positions = await _gantry.GetAllAbsolutePositionsAsync();
                AbsPos1 = positions.Axis1; AbsPos2 = positions.Axis2; AbsPos3 = positions.Axis3;
                AbsPos4 = positions.Axis4; AbsPos5 = positions.Axis5; AbsPos6 = positions.Axis6;
            }
            catch (Exception ex)
            {
                LoggerHelper.Error($"[BenchMovement] 读取设备参数失败: {ex.Message}");
            }
        }

        private async void OnPollTick(object? sender, EventArgs e)
        {
            if (_gantry == null || !_gantry.IsConnected) return;
            try
            {
                // 批量读取 6 轴绝对位置（一次性通信，高效）
                var pos = await _gantry.GetAllAbsolutePositionsAsync();
                AbsPos1 = pos.Axis1; AbsPos2 = pos.Axis2; AbsPos3 = pos.Axis3;
                AbsPos4 = pos.Axis4; AbsPos5 = pos.Axis5; AbsPos6 = pos.Axis6;
            }
            catch { /* 忽略轮询错误 */ }
        }

        #endregion

        #region 生命周期

        public override void OnNavigatedTo(NavigationContext navigationContext)
        {
            base.OnNavigatedTo(navigationContext);
            if (!_isInitiated)
            {
                _isInitiated = true;
                InitGantryFromDeviceManager();
            }
        }

        /// <summary>
        /// 从 DeviceManager.DeviceMap 中查找 GantryControlTcp 实例，
        /// 优先使用当前打开的作用域，找不到则取任意已注册作用域。
        /// </summary>
        private void InitGantryFromDeviceManager()
        {
            try
            {
                // 优先使用当前打开的作用域
                IScopedProvider? scope = null;
                if (!string.IsNullOrEmpty(_globalInfo.CurrentOpeningScope)
                    && _globalInfo.ScopeDic.TryGetValue(_globalInfo.CurrentOpeningScope, out scope))
                {
                    // 找到了
                }
                else
                {
                    // 退而求其次，取任意可用作用域
                    scope = _globalInfo.ScopeDic.Values.FirstOrDefault();
                }

                if (scope == null)
                {
                    LoggerHelper.Warn("[BenchMovement] 无可用的作用域，无法解析 DeviceManager。");
                    return;
                }

                _deviceManager = scope.Resolve<DeviceManager>();
                _gantry = _deviceManager.DeviceMap.Values.OfType<GantryControlTcp>().FirstOrDefault();

                if (_gantry != null)
                {
                    LoggerHelper.Info($"[BenchMovement] 已从 DeviceManager 获取 GantryControlTcp 实例。");
                    UpdateConnectionStatus();
                }
                else
                {
                    LoggerHelper.Warn("[BenchMovement] DeviceManager 中未找到 GantryControlTcp 设备，请检查设备配置。");
                }
            }
            catch (Exception ex)
            {
                LoggerHelper.Error($"[BenchMovement] 初始化 GantryControlTcp 失败: {ex.Message}");
            }
        }

        public void Dispose()
        {
            _pollTimer.Stop();
            // GantryControlTcp 由 DeviceManager 统一管理生命周期，此处仅停止轮询
        }

        #endregion
    }
}
