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>
    /// IT7800E 交直流电源控制面板 ViewModel。
    /// <para>
    /// 注册为 Navigation View，既可由 Region 导航进入，
    /// 也可由外部直接实例化后作为 Tab 内容塞入 DialogMangerView：
    /// <code>
    /// var view = container.Resolve&lt;IT7800EView&gt;();
    /// (view.DataContext as IT7800EViewModel)?.Initialize("IT7800E");
    /// _eventAggregator.GetEvent&lt;AddDialogTabEvent&gt;().Publish(
    ///     new DialogTabInfo { Title = "IT7800E", Content = view });
    /// </code>
    /// </para>
    /// </summary>
    public class IT7800EViewModel : NavigateViewModelBase, IDisposable
    {
        #region 私有字段

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

        #endregion

        #region 设备信息属性

        private string _deviceName = "IT7800E";
        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;
        /// <summary>正在执行设备命令时为 true，用于 UI 忙碌状态指示。</summary>
        public bool IsBusy
        {
            get => _isBusy;
            set => SetProperty(ref _isBusy, value);
        }

        #endregion

        #region 输入参数属性

        private double _acVoltage = 220.0;
        /// <summary>待设置的交流电压值（V）。</summary>
        public double AcVoltage
        {
            get => _acVoltage;
            set => SetProperty(ref _acVoltage, value);
        }

        private double _dcVoltage = 0.0;
        /// <summary>待设置的直流偏置电压值（V）。</summary>
        public double DcVoltage
        {
            get => _dcVoltage;
            set => SetProperty(ref _dcVoltage, value);
        }

        private double _frequency = 50.0;
        /// <summary>待设置的交流频率（Hz）。</summary>
        public double Frequency
        {
            get => _frequency;
            set => SetProperty(ref _frequency, value);
        }

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

        private PowerCouplingMode _selectedMode = PowerCouplingMode.AC;
        /// <summary>待设置的电源工作模式：AC / DC / ACDC。</summary>
        public PowerCouplingMode SelectedMode
        {
            get => _selectedMode;
            set => SetProperty(ref _selectedMode, value);
        }

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

        private double _ocpValue = 15.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 _measuredFrequency = "—";
        public string MeasuredFrequency
        {
            get => _measuredFrequency;
            set => SetProperty(ref _measuredFrequency, 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 ResetDeviceCommand     { get; }
        public ICommand OutputOnCommand        { get; }
        public ICommand OutputOffCommand       { get; }
        public ICommand SetModeCommand         { get; }
        public ICommand SetAcVoltageCommand    { get; }
        public ICommand SetDcVoltageCommand    { get; }
        public ICommand SetFrequencyCommand    { get; }
        public ICommand SetCurrentCommand      { get; }
        public ICommand QueryAllMeasureCommand { get; }
        public ICommand SetRemoteModeCommand   { get; }
        public ICommand SetLocalModeCommand    { get; }
        public ICommand SetOvpCommand          { get; }
        public ICommand SetOcpCommand          { get; }
        public ICommand ClearAlarmCommand      { get; }
        public ICommand ClearErrorCommand      { get; }

        #endregion

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

            QueryIdentityCommand   = new DelegateCommand(async () => await Exec(async () => AppendLog("IDN: " + await _device!.查询设备标识(Ct()))));
            ResetDeviceCommand     = new DelegateCommand(async () => await Exec(async () => { await _device!.重置设备(Ct()); AppendLog("设备已重置"); }));
            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("输出已关闭"); }));
            SetModeCommand         = new DelegateCommand(async () => await Exec(async () => { await _device!.设置电源模式(SelectedMode, Ct()); AppendLog($"模式已设为 {SelectedMode}"); }));
            SetAcVoltageCommand    = new DelegateCommand(async () => await Exec(async () => { await _device!.设置交流电压(AcVoltage, Ct()); AppendLog($"AC电压已设为 {AcVoltage} V"); }));
            SetDcVoltageCommand    = new DelegateCommand(async () => await Exec(async () => { await _device!.设置直流电压(DcVoltage, Ct()); AppendLog($"DC偏置已设为 {DcVoltage} V"); }));
            SetFrequencyCommand    = new DelegateCommand(async () => await Exec(async () => { await _device!.设置频率(Frequency, Ct()); AppendLog($"频率已设为 {Frequency} Hz"); }));
            SetCurrentCommand      = new DelegateCommand(async () => await Exec(async () => { await _device!.设置电流(CurrentLimit, Ct()); AppendLog($"限流已设为 {CurrentLimit} A"); }));
            SetOvpCommand          = new DelegateCommand(async () => await Exec(async () => { await _device!.设置过压保护_OVP(OvpValue, Ct()); AppendLog($"OVP已设为 {OvpValue} V"); }));
            SetOcpCommand          = new DelegateCommand(async () => await Exec(async () => { await _device!.设置过流保护_OCP(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("已切换到本地控制模式"); }));
            ClearAlarmCommand      = new DelegateCommand(async () => await Exec(async () => { await _device!.清除保护告警(Ct()); AppendLog("保护告警已清除"); }));
            ClearErrorCommand      = new DelegateCommand(async () => await Exec(async () => { await _device!.清除错误队列和状态字节(Ct()); AppendLog("错误队列已清除"); }));

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

            Initialize();
        }

        #region 初始化 / Navigation

        /// <summary>
        /// 从 DeviceManager 中查找 IT7800E 设备实例。
        /// 优先按 <paramref name="deviceName"/> 查找，否则取第一个匹配类型的设备。
        /// </summary>
        public void Initialize(string? deviceName = null)
        {
            IT7800E? found = null;
            string? foundName = null;

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

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

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

        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();
        }
    }
}
