using DeviceCommand.Devices;
using Prism.Commands;
using Prism.Ioc;
using System;
using System.Threading;
using System.Windows.Input;
using UIShare.GlobalVariable;
using UIShare.ViewModelBase;

namespace DeviceEditModule.ViewModels
{
    /// <summary>
    /// N36600 便携式宽范围可编程直流电源控制面板 ViewModel。
    /// </summary>
    public class N36600ViewModel : NavigateViewModelBase, IDisposable
    {
        #region 私有字段

        private readonly DeviceManager _deviceManager;
        private N36600? _device;
        private CancellationTokenSource? _cts;

        #endregion

        #region 设备信息属性

        private string _deviceName = "N36600";
        public string DeviceName
        {
            get => _deviceName;
            set => SetProperty(ref _deviceName, value);
        }

        private bool _isConnected;
        public bool IsConnected
        {
            get => _isConnected;
            set => SetProperty(ref _isConnected, value);
        }

        private bool _isBusy;
        public bool IsBusy
        {
            get => _isBusy;
            set => SetProperty(ref _isBusy, value);
        }

        #endregion

        #region 输入参数属性

        private double _voltage = 12.0;
        /// <summary>待设置的输出电压值（V）。</summary>
        public double Voltage
        {
            get => _voltage;
            set => SetProperty(ref _voltage, value);
        }

        private double _currentLimit = 5.0;
        /// <summary>待设置的输出电流值（A）。</summary>
        public double CurrentLimit
        {
            get => _currentLimit;
            set => SetProperty(ref _currentLimit, value);
        }

        private double _power = 60.0;
        /// <summary>待设置的输出功率值（W）。</summary>
        public double Power
        {
            get => _power;
            set => SetProperty(ref _power, value);
        }

        private double _ovpValue = 15.0;
        /// <summary>过压保护值（V）。</summary>
        public double OvpValue
        {
            get => _ovpValue;
            set => SetProperty(ref _ovpValue, value);
        }

        private double _ocpValue = 6.0;
        /// <summary>过流保护值（A）。</summary>
        public double OcpValue
        {
            get => _ocpValue;
            set => SetProperty(ref _ocpValue, value);
        }

        #endregion

        #region 测量结果属性

        private string _measuredVoltage = "—";
        public string MeasuredVoltage
        {
            get => _measuredVoltage;
            set => SetProperty(ref _measuredVoltage, value);
        }

        private string _measuredCurrent = "—";
        public string MeasuredCurrent
        {
            get => _measuredCurrent;
            set => SetProperty(ref _measuredCurrent, value);
        }

        private string _measuredPower = "—";
        public string MeasuredPower
        {
            get => _measuredPower;
            set => SetProperty(ref _measuredPower, value);
        }

        private string _outputState = "—";
        /// <summary>当前 DC 输出状态（OUTPut? 查询结果）。</summary>
        public string OutputState
        {
            get => _outputState;
            set => SetProperty(ref _outputState, value);
        }

        private string _responseLog = string.Empty;
        /// <summary>命令响应日志（最新消息在顶部）。</summary>
        public string ResponseLog
        {
            get => _responseLog;
            set => SetProperty(ref _responseLog, value);
        }

        #endregion

        #region 命令

        public ICommand QueryIdentityCommand            { get; }
        public ICommand OutputOnCommand                 { get; }
        public ICommand OutputOffCommand                { get; }
        public ICommand SetVoltageCommand               { get; }
        public ICommand SetCurrentCommand               { get; }
        public ICommand SetPowerCommand                 { get; }
        public ICommand SetOvpCommand                   { get; }
        public ICommand SetOcpCommand                   { get; }
        public ICommand QueryAllMeasureCommand          { get; }
        public ICommand QueryOutputStateCommand         { get; }
        public ICommand SetRemoteModeCommand            { get; }
        public ICommand SetLocalModeCommand             { get; }
        public ICommand ClearVoltageProtectionCommand   { get; }
        public ICommand ClearCurrentProtectionCommand   { get; }

        #endregion

        public N36600ViewModel(IContainerProvider containerProvider) : base(containerProvider)
        {
            _deviceManager = containerProvider.Resolve<DeviceManager>();

            QueryIdentityCommand          = new DelegateCommand(async () => await Exec(async () => AppendLog("IDN: " + await _device!.查询设备标识(Ct()))));
            OutputOnCommand               = new DelegateCommand(async () => await Exec(async () => { await _device!.设置DC输出(true, Ct()); AppendLog("输出已开启"); }));
            OutputOffCommand              = new DelegateCommand(async () => await Exec(async () => { await _device!.设置DC输出(false, Ct()); AppendLog("输出已关闭"); }));
            SetVoltageCommand             = new DelegateCommand(async () => await Exec(async () => { await _device!.设置电压(Voltage, Ct()); AppendLog($"电压已设为 {Voltage} V"); }));
            SetCurrentCommand             = new DelegateCommand(async () => await Exec(async () => { await _device!.设置电流(CurrentLimit, Ct()); AppendLog($"电流已设为 {CurrentLimit} A"); }));
            SetPowerCommand               = new DelegateCommand(async () => await Exec(async () => { await _device!.设置功率(Power, Ct()); AppendLog($"功率已设为 {Power} W"); }));
            SetOvpCommand                 = new DelegateCommand(async () => await Exec(async () => { await _device!.设置过压保护值(OvpValue, Ct()); AppendLog($"OVP已设为 {OvpValue} V"); }));
            SetOcpCommand                 = new DelegateCommand(async () => await Exec(async () => { await _device!.设置过流保护值(OcpValue, Ct()); AppendLog($"OCP已设为 {OcpValue} A"); }));
            SetRemoteModeCommand          = new DelegateCommand(async () => await Exec(async () => { await _device!.切换远程控制模式(Ct()); AppendLog("已切换到远程控制模式"); }));
            SetLocalModeCommand           = new DelegateCommand(async () => await Exec(async () => { await _device!.切换本地控制模式(Ct()); AppendLog("已切换到本地控制模式"); }));
            ClearVoltageProtectionCommand = new DelegateCommand(async () => await Exec(async () => { await _device!.清除电压保护状态(Ct()); AppendLog("电压保护状态已清除"); }));
            ClearCurrentProtectionCommand = new DelegateCommand(async () => await Exec(async () => { await _device!.清除电流保护状态(Ct()); AppendLog("电流保护状态已清除"); }));

            QueryOutputStateCommand = new DelegateCommand(async () => await Exec(async () =>
            {
                OutputState = await _device!.查询DC输出状态(Ct());
                AppendLog($"输出状态: {OutputState}");
            }));

            QueryAllMeasureCommand = new DelegateCommand(async () => await Exec(async () =>
            {
                MeasuredVoltage = await _device!.查询实际电压(Ct());
                MeasuredCurrent = await _device!.查询实际电流(Ct());
                MeasuredPower   = await _device!.查询实际功率(Ct());
                AppendLog($"测量 → 电压:{MeasuredVoltage}V 电流:{MeasuredCurrent}A 功率:{MeasuredPower}W");
            }));

            Initialize();
        }

        #region 初始化 / Navigation

        public void Initialize(string? deviceName = null)
        {
            N36600? found = null;
            string? foundName = null;

            if (deviceName != null &&
                _deviceManager.DeviceMap.TryGetValue(deviceName, out var d) &&
                d is N36600 n)
            {
                found = n;
                foundName = deviceName;
            }
            else
            {
                foreach (var kv in _deviceManager.DeviceMap)
                {
                    if (kv.Value is N36600 n36)
                    {
                        found = n36;
                        foundName = kv.Key;
                        break;
                    }
                }
            }

            _device     = found;
            DeviceName  = foundName ?? "N36600 (未找到)";
            IsConnected = _device?.IsConnected ?? false;

            AppendLog(found != null
                ? $"已关联设备 [{DeviceName}]，连接状态：{(IsConnected ? "已连接" : "未连接")}"
                : "未在 DeviceManager 中找到 N36600 设备，请先初始化设备配置。");
        }

        public override void OnNavigatedTo(NavigationContext context)
        {
            var name = context.Parameters.GetValue<string?>("DeviceName");
            Initialize(name);
        }

        #endregion

        #region 辅助

        private CancellationToken Ct() => (_cts = new CancellationTokenSource(TimeSpan.FromSeconds(10))).Token;

        private async Task Exec(Func<Task> action)
        {
            if (_device == null)
            {
                AppendLog("错误：未关联到设备实例，请检查设备配置。");
                return;
            }
            if (IsBusy) return;
            IsBusy = true;
            try
            {
                await action();
                IsConnected = _device.IsConnected;
            }
            catch (OperationCanceledException)
            {
                AppendLog("命令超时或已取消。");
            }
            catch (Exception ex)
            {
                AppendLog($"错误：{ex.Message}");
            }
            finally
            {
                IsBusy = false;
            }
        }

        private void AppendLog(string message)
        {
            var line = $"[{DateTime.Now:HH:mm:ss}] {message}";
            ResponseLog = ResponseLog.Length > 4000
                ? line + "\n" + ResponseLog[..3000]
                : line + "\n" + ResponseLog;
        }

        #endregion

        public void Dispose()
        {
            _cts?.Cancel();
            _cts?.Dispose();
        }
    }
}
